os/ossrv/ssl/libcrypto/src/crypto/x509/x509_req.c
changeset 0 bde4ae8d615e
     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 +}