1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/x509/x509_req.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,341 @@
1.4 +/* crypto/x509/x509_req.c */
1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.6 + * All rights reserved.
1.7 + *
1.8 + * This package is an SSL implementation written
1.9 + * by Eric Young (eay@cryptsoft.com).
1.10 + * The implementation was written so as to conform with Netscapes SSL.
1.11 + *
1.12 + * This library is free for commercial and non-commercial use as long as
1.13 + * the following conditions are aheared to. The following conditions
1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
1.15 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.16 + * included with this distribution is covered by the same copyright terms
1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.18 + *
1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.20 + * the code are not to be removed.
1.21 + * If this package is used in a product, Eric Young should be given attribution
1.22 + * as the author of the parts of the library used.
1.23 + * This can be in the form of a textual message at program startup or
1.24 + * in documentation (online or textual) provided with the package.
1.25 + *
1.26 + * Redistribution and use in source and binary forms, with or without
1.27 + * modification, are permitted provided that the following conditions
1.28 + * are met:
1.29 + * 1. Redistributions of source code must retain the copyright
1.30 + * notice, this list of conditions and the following disclaimer.
1.31 + * 2. Redistributions in binary form must reproduce the above copyright
1.32 + * notice, this list of conditions and the following disclaimer in the
1.33 + * documentation and/or other materials provided with the distribution.
1.34 + * 3. All advertising materials mentioning features or use of this software
1.35 + * must display the following acknowledgement:
1.36 + * "This product includes cryptographic software written by
1.37 + * Eric Young (eay@cryptsoft.com)"
1.38 + * The word 'cryptographic' can be left out if the rouines from the library
1.39 + * being used are not cryptographic related :-).
1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.41 + * the apps directory (application code) you must include an acknowledgement:
1.42 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.43 + *
1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.47 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.54 + * SUCH DAMAGE.
1.55 + *
1.56 + * The licence and distribution terms for any publically available version or
1.57 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.58 + * copied and put under another distribution licence
1.59 + * [including the GNU Public Licence.]
1.60 + */
1.61 + /*
1.62 + © Portions copyright (c) 2006 Nokia Corporation. All rights reserved.
1.63 + */
1.64 +
1.65 +
1.66 +#include <stdio.h>
1.67 +#include "cryptlib.h"
1.68 +#include <openssl/bn.h>
1.69 +#include <openssl/evp.h>
1.70 +#include <openssl/asn1.h>
1.71 +#include <openssl/x509.h>
1.72 +#include <openssl/objects.h>
1.73 +#include <openssl/buffer.h>
1.74 +#include <openssl/pem.h>
1.75 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
1.76 +#include "libcrypto_wsd_macros.h"
1.77 +#include "libcrypto_wsd.h"
1.78 +#endif
1.79 +
1.80 +
1.81 +
1.82 +EXPORT_C X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
1.83 + {
1.84 + X509_REQ *ret;
1.85 + X509_REQ_INFO *ri;
1.86 + int i;
1.87 + EVP_PKEY *pktmp;
1.88 +
1.89 + ret=X509_REQ_new();
1.90 + if (ret == NULL)
1.91 + {
1.92 + X509err(X509_F_X509_TO_X509_REQ,ERR_R_MALLOC_FAILURE);
1.93 + goto err;
1.94 + }
1.95 +
1.96 + ri=ret->req_info;
1.97 +
1.98 + ri->version->length=1;
1.99 + ri->version->data=(unsigned char *)OPENSSL_malloc(1);
1.100 + if (ri->version->data == NULL) goto err;
1.101 + ri->version->data[0]=0; /* version == 0 */
1.102 +
1.103 + if (!X509_REQ_set_subject_name(ret,X509_get_subject_name(x)))
1.104 + goto err;
1.105 +
1.106 + pktmp = X509_get_pubkey(x);
1.107 + i=X509_REQ_set_pubkey(ret,pktmp);
1.108 + EVP_PKEY_free(pktmp);
1.109 + if (!i) goto err;
1.110 +
1.111 + if (pkey != NULL)
1.112 + {
1.113 + if (!X509_REQ_sign(ret,pkey,md))
1.114 + goto err;
1.115 + }
1.116 + return(ret);
1.117 +err:
1.118 + X509_REQ_free(ret);
1.119 + return(NULL);
1.120 + }
1.121 +
1.122 +EXPORT_C EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
1.123 + {
1.124 + if ((req == NULL) || (req->req_info == NULL))
1.125 + return(NULL);
1.126 + return(X509_PUBKEY_get(req->req_info->pubkey));
1.127 + }
1.128 +
1.129 +EXPORT_C int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
1.130 + {
1.131 + EVP_PKEY *xk=NULL;
1.132 + int ok=0;
1.133 +
1.134 + xk=X509_REQ_get_pubkey(x);
1.135 + switch (EVP_PKEY_cmp(xk, k))
1.136 + {
1.137 + case 1:
1.138 + ok=1;
1.139 + break;
1.140 + case 0:
1.141 + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
1.142 + break;
1.143 + case -1:
1.144 + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
1.145 + break;
1.146 + case -2:
1.147 +#ifndef OPENSSL_NO_EC
1.148 + if (k->type == EVP_PKEY_EC)
1.149 + {
1.150 + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
1.151 + break;
1.152 + }
1.153 +#endif
1.154 +#ifndef OPENSSL_NO_DH
1.155 + if (k->type == EVP_PKEY_DH)
1.156 + {
1.157 + /* No idea */
1.158 + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY);
1.159 + break;
1.160 + }
1.161 +#endif
1.162 + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
1.163 + }
1.164 +
1.165 + EVP_PKEY_free(xk);
1.166 + return(ok);
1.167 + }
1.168 +
1.169 +/* It seems several organisations had the same idea of including a list of
1.170 + * extensions in a certificate request. There are at least two OIDs that are
1.171 + * used and there may be more: so the list is configurable.
1.172 + */
1.173 +#ifndef EMULATOR
1.174 +static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef};
1.175 +static int *ext_nids = ext_nid_list;
1.176 +#else
1.177 +GET_STATIC_VAR_FROM_TLS(ext_nids,x509_req,int*)
1.178 +#define ext_nids (*GET_WSD_VAR_NAME(ext_nids,x509_req, s)())
1.179 +
1.180 +GET_STATIC_ARRAY_FROM_TLS(ext_nid_list,x509_req,int)
1.181 +#define ext_nid_list (GET_WSD_VAR_NAME(ext_nid_list,x509_req, s)())
1.182 +
1.183 +#endif
1.184 +
1.185 +EXPORT_C int X509_REQ_extension_nid(int req_nid)
1.186 +{
1.187 + int i, nid;
1.188 + for(i = 0; ; i++) {
1.189 + nid = ext_nids[i];
1.190 + if(nid == NID_undef) return 0;
1.191 + else if (req_nid == nid) return 1;
1.192 + }
1.193 +}
1.194 +
1.195 +EXPORT_C int *X509_REQ_get_extension_nids(void)
1.196 +{
1.197 + return ext_nids;
1.198 +}
1.199 +
1.200 +EXPORT_C void X509_REQ_set_extension_nids(int *nids)
1.201 +{
1.202 + ext_nids = nids;
1.203 +}
1.204 +
1.205 +EXPORT_C STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
1.206 + {
1.207 + X509_ATTRIBUTE *attr;
1.208 + ASN1_TYPE *ext = NULL;
1.209 + int idx, *pnid;
1.210 + const unsigned char *p;
1.211 +
1.212 + if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
1.213 + return(NULL);
1.214 + for (pnid = ext_nids; *pnid != NID_undef; pnid++)
1.215 + {
1.216 + idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
1.217 + if (idx == -1)
1.218 + continue;
1.219 + attr = X509_REQ_get_attr(req, idx);
1.220 + if(attr->single) ext = attr->value.single;
1.221 + else if(sk_ASN1_TYPE_num(attr->value.set))
1.222 + ext = sk_ASN1_TYPE_value(attr->value.set, 0);
1.223 + break;
1.224 + }
1.225 + if(!ext || (ext->type != V_ASN1_SEQUENCE))
1.226 + return NULL;
1.227 + p = ext->value.sequence->data;
1.228 + return d2i_ASN1_SET_OF_X509_EXTENSION(NULL, &p,
1.229 + ext->value.sequence->length,
1.230 + d2i_X509_EXTENSION, X509_EXTENSION_free,
1.231 + V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
1.232 +}
1.233 +
1.234 +/* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
1.235 + * in case we want to create a non standard one.
1.236 + */
1.237 +
1.238 +EXPORT_C int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
1.239 + int nid)
1.240 +{
1.241 + unsigned char *p = NULL, *q;
1.242 + long len;
1.243 + ASN1_TYPE *at = NULL;
1.244 + X509_ATTRIBUTE *attr = NULL;
1.245 + if(!(at = ASN1_TYPE_new()) ||
1.246 + !(at->value.sequence = ASN1_STRING_new())) goto err;
1.247 +
1.248 + at->type = V_ASN1_SEQUENCE;
1.249 + /* Generate encoding of extensions */
1.250 + len = i2d_ASN1_SET_OF_X509_EXTENSION(exts, NULL, i2d_X509_EXTENSION,
1.251 + V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE);
1.252 + if(!(p = OPENSSL_malloc(len))) goto err;
1.253 + q = p;
1.254 + i2d_ASN1_SET_OF_X509_EXTENSION(exts, &q, i2d_X509_EXTENSION,
1.255 + V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE);
1.256 + at->value.sequence->data = p;
1.257 + p = NULL;
1.258 + at->value.sequence->length = len;
1.259 + if(!(attr = X509_ATTRIBUTE_new())) goto err;
1.260 + if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
1.261 + if(!sk_ASN1_TYPE_push(attr->value.set, at)) goto err;
1.262 + at = NULL;
1.263 + attr->single = 0;
1.264 + attr->object = OBJ_nid2obj(nid);
1.265 + if (!req->req_info->attributes)
1.266 + {
1.267 + if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
1.268 + goto err;
1.269 + }
1.270 + if(!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) goto err;
1.271 + return 1;
1.272 + err:
1.273 + if(p) OPENSSL_free(p);
1.274 + X509_ATTRIBUTE_free(attr);
1.275 + ASN1_TYPE_free(at);
1.276 + return 0;
1.277 +}
1.278 +/* This is the normal usage: use the "official" OID */
1.279 +EXPORT_C int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts)
1.280 +{
1.281 + return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
1.282 +}
1.283 +
1.284 +/* Request attribute functions */
1.285 +
1.286 +EXPORT_C int X509_REQ_get_attr_count(const X509_REQ *req)
1.287 +{
1.288 + return X509at_get_attr_count(req->req_info->attributes);
1.289 +}
1.290 +
1.291 +EXPORT_C int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
1.292 + int lastpos)
1.293 +{
1.294 + return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos);
1.295 +}
1.296 +
1.297 +EXPORT_C int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
1.298 + int lastpos)
1.299 +{
1.300 + return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos);
1.301 +}
1.302 +
1.303 +EXPORT_C X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc)
1.304 +{
1.305 + return X509at_get_attr(req->req_info->attributes, loc);
1.306 +}
1.307 +
1.308 +EXPORT_C X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc)
1.309 +{
1.310 + return X509at_delete_attr(req->req_info->attributes, loc);
1.311 +}
1.312 +
1.313 +EXPORT_C int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr)
1.314 +{
1.315 + if(X509at_add1_attr(&req->req_info->attributes, attr)) return 1;
1.316 + return 0;
1.317 +}
1.318 +
1.319 +EXPORT_C int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
1.320 + const ASN1_OBJECT *obj, int type,
1.321 + const unsigned char *bytes, int len)
1.322 +{
1.323 + if(X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj,
1.324 + type, bytes, len)) return 1;
1.325 + return 0;
1.326 +}
1.327 +
1.328 +EXPORT_C int X509_REQ_add1_attr_by_NID(X509_REQ *req,
1.329 + int nid, int type,
1.330 + const unsigned char *bytes, int len)
1.331 +{
1.332 + if(X509at_add1_attr_by_NID(&req->req_info->attributes, nid,
1.333 + type, bytes, len)) return 1;
1.334 + return 0;
1.335 +}
1.336 +
1.337 +EXPORT_C int X509_REQ_add1_attr_by_txt(X509_REQ *req,
1.338 + const char *attrname, int type,
1.339 + const unsigned char *bytes, int len)
1.340 +{
1.341 + if(X509at_add1_attr_by_txt(&req->req_info->attributes, attrname,
1.342 + type, bytes, len)) return 1;
1.343 + return 0;
1.344 +}