xref: /freebsd/crypto/openssl/crypto/x509/x509_req.c (revision 6be8ae07)
174664626SKris Kennaway /* crypto/x509/x509_req.c */
274664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
374664626SKris Kennaway  * All rights reserved.
474664626SKris Kennaway  *
574664626SKris Kennaway  * This package is an SSL implementation written
674664626SKris Kennaway  * by Eric Young (eay@cryptsoft.com).
774664626SKris Kennaway  * The implementation was written so as to conform with Netscapes SSL.
874664626SKris Kennaway  *
974664626SKris Kennaway  * This library is free for commercial and non-commercial use as long as
1074664626SKris Kennaway  * the following conditions are aheared to.  The following conditions
1174664626SKris Kennaway  * apply to all code found in this distribution, be it the RC4, RSA,
1274664626SKris Kennaway  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1374664626SKris Kennaway  * included with this distribution is covered by the same copyright terms
1474664626SKris Kennaway  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1574664626SKris Kennaway  *
1674664626SKris Kennaway  * Copyright remains Eric Young's, and as such any Copyright notices in
1774664626SKris Kennaway  * the code are not to be removed.
1874664626SKris Kennaway  * If this package is used in a product, Eric Young should be given attribution
1974664626SKris Kennaway  * as the author of the parts of the library used.
2074664626SKris Kennaway  * This can be in the form of a textual message at program startup or
2174664626SKris Kennaway  * in documentation (online or textual) provided with the package.
2274664626SKris Kennaway  *
2374664626SKris Kennaway  * Redistribution and use in source and binary forms, with or without
2474664626SKris Kennaway  * modification, are permitted provided that the following conditions
2574664626SKris Kennaway  * are met:
2674664626SKris Kennaway  * 1. Redistributions of source code must retain the copyright
2774664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer.
2874664626SKris Kennaway  * 2. Redistributions in binary form must reproduce the above copyright
2974664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer in the
3074664626SKris Kennaway  *    documentation and/or other materials provided with the distribution.
3174664626SKris Kennaway  * 3. All advertising materials mentioning features or use of this software
3274664626SKris Kennaway  *    must display the following acknowledgement:
3374664626SKris Kennaway  *    "This product includes cryptographic software written by
3474664626SKris Kennaway  *     Eric Young (eay@cryptsoft.com)"
3574664626SKris Kennaway  *    The word 'cryptographic' can be left out if the rouines from the library
3674664626SKris Kennaway  *    being used are not cryptographic related :-).
3774664626SKris Kennaway  * 4. If you include any Windows specific code (or a derivative thereof) from
3874664626SKris Kennaway  *    the apps directory (application code) you must include an acknowledgement:
3974664626SKris Kennaway  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4074664626SKris Kennaway  *
4174664626SKris Kennaway  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4274664626SKris Kennaway  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4374664626SKris Kennaway  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4474664626SKris Kennaway  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4574664626SKris Kennaway  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4674664626SKris Kennaway  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4774664626SKris Kennaway  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4874664626SKris Kennaway  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4974664626SKris Kennaway  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5074664626SKris Kennaway  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5174664626SKris Kennaway  * SUCH DAMAGE.
5274664626SKris Kennaway  *
5374664626SKris Kennaway  * The licence and distribution terms for any publically available version or
5474664626SKris Kennaway  * derivative of this code cannot be changed.  i.e. this code cannot simply be
5574664626SKris Kennaway  * copied and put under another distribution licence
5674664626SKris Kennaway  * [including the GNU Public Licence.]
5774664626SKris Kennaway  */
5874664626SKris Kennaway 
5974664626SKris Kennaway #include <stdio.h>
6074664626SKris Kennaway #include "cryptlib.h"
6174664626SKris Kennaway #include <openssl/bn.h>
6274664626SKris Kennaway #include <openssl/evp.h>
6374664626SKris Kennaway #include <openssl/asn1.h>
6474664626SKris Kennaway #include <openssl/x509.h>
6574664626SKris Kennaway #include <openssl/objects.h>
6674664626SKris Kennaway #include <openssl/buffer.h>
6774664626SKris Kennaway #include <openssl/pem.h>
6874664626SKris Kennaway 
69f579bf8eSKris Kennaway X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
7074664626SKris Kennaway 	{
7174664626SKris Kennaway 	X509_REQ *ret;
7274664626SKris Kennaway 	X509_REQ_INFO *ri;
7374664626SKris Kennaway 	int i;
7474664626SKris Kennaway 	EVP_PKEY *pktmp;
7574664626SKris Kennaway 
7674664626SKris Kennaway 	ret=X509_REQ_new();
7774664626SKris Kennaway 	if (ret == NULL)
7874664626SKris Kennaway 		{
7974664626SKris Kennaway 		X509err(X509_F_X509_TO_X509_REQ,ERR_R_MALLOC_FAILURE);
8074664626SKris Kennaway 		goto err;
8174664626SKris Kennaway 		}
8274664626SKris Kennaway 
8374664626SKris Kennaway 	ri=ret->req_info;
8474664626SKris Kennaway 
8574664626SKris Kennaway 	ri->version->length=1;
86ddd58736SKris Kennaway 	ri->version->data=(unsigned char *)OPENSSL_malloc(1);
8774664626SKris Kennaway 	if (ri->version->data == NULL) goto err;
8874664626SKris Kennaway 	ri->version->data[0]=0; /* version == 0 */
8974664626SKris Kennaway 
9074664626SKris Kennaway 	if (!X509_REQ_set_subject_name(ret,X509_get_subject_name(x)))
9174664626SKris Kennaway 		goto err;
9274664626SKris Kennaway 
9374664626SKris Kennaway 	pktmp = X509_get_pubkey(x);
9474664626SKris Kennaway 	i=X509_REQ_set_pubkey(ret,pktmp);
9574664626SKris Kennaway 	EVP_PKEY_free(pktmp);
9674664626SKris Kennaway 	if (!i) goto err;
9774664626SKris Kennaway 
9874664626SKris Kennaway 	if (pkey != NULL)
9974664626SKris Kennaway 		{
10074664626SKris Kennaway 		if (!X509_REQ_sign(ret,pkey,md))
10174664626SKris Kennaway 			goto err;
10274664626SKris Kennaway 		}
10374664626SKris Kennaway 	return(ret);
10474664626SKris Kennaway err:
10574664626SKris Kennaway 	X509_REQ_free(ret);
10674664626SKris Kennaway 	return(NULL);
10774664626SKris Kennaway 	}
10874664626SKris Kennaway 
10974664626SKris Kennaway EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
11074664626SKris Kennaway 	{
11174664626SKris Kennaway 	if ((req == NULL) || (req->req_info == NULL))
11274664626SKris Kennaway 		return(NULL);
11374664626SKris Kennaway 	return(X509_PUBKEY_get(req->req_info->pubkey));
11474664626SKris Kennaway 	}
11574664626SKris Kennaway 
116f579bf8eSKris Kennaway /* It seems several organisations had the same idea of including a list of
117f579bf8eSKris Kennaway  * extensions in a certificate request. There are at least two OIDs that are
118f579bf8eSKris Kennaway  * used and there may be more: so the list is configurable.
119f579bf8eSKris Kennaway  */
120f579bf8eSKris Kennaway 
1216be8ae07SJacques Vidrine static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef};
122f579bf8eSKris Kennaway 
123f579bf8eSKris Kennaway static int *ext_nids = ext_nid_list;
124f579bf8eSKris Kennaway 
125f579bf8eSKris Kennaway int X509_REQ_extension_nid(int req_nid)
126f579bf8eSKris Kennaway {
127f579bf8eSKris Kennaway 	int i, nid;
128f579bf8eSKris Kennaway 	for(i = 0; ; i++) {
129f579bf8eSKris Kennaway 		nid = ext_nids[i];
130f579bf8eSKris Kennaway 		if(nid == NID_undef) return 0;
131f579bf8eSKris Kennaway 		else if (req_nid == nid) return 1;
132f579bf8eSKris Kennaway 	}
133f579bf8eSKris Kennaway }
134f579bf8eSKris Kennaway 
135f579bf8eSKris Kennaway int *X509_REQ_get_extension_nids(void)
136f579bf8eSKris Kennaway {
137f579bf8eSKris Kennaway 	return ext_nids;
138f579bf8eSKris Kennaway }
139f579bf8eSKris Kennaway 
140f579bf8eSKris Kennaway void X509_REQ_set_extension_nids(int *nids)
141f579bf8eSKris Kennaway {
142f579bf8eSKris Kennaway 	ext_nids = nids;
143f579bf8eSKris Kennaway }
144f579bf8eSKris Kennaway 
145f579bf8eSKris Kennaway STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
146f579bf8eSKris Kennaway 	{
147f579bf8eSKris Kennaway 	X509_ATTRIBUTE *attr;
148f579bf8eSKris Kennaway 	ASN1_TYPE *ext = NULL;
1496be8ae07SJacques Vidrine 	int idx, *pnid;
150f579bf8eSKris Kennaway 	unsigned char *p;
1516be8ae07SJacques Vidrine 
1526be8ae07SJacques Vidrine 	if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
153f579bf8eSKris Kennaway 		return(NULL);
1546be8ae07SJacques Vidrine 	for (pnid = ext_nids; *pnid != NID_undef; pnid++)
1556be8ae07SJacques Vidrine 		{
1566be8ae07SJacques Vidrine 		idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
1576be8ae07SJacques Vidrine 		if (idx == -1)
1586be8ae07SJacques Vidrine 			continue;
1596be8ae07SJacques Vidrine 		attr = X509_REQ_get_attr(req, idx);
1605c87c606SMark Murray 		if(attr->single) ext = attr->value.single;
1615c87c606SMark Murray 		else if(sk_ASN1_TYPE_num(attr->value.set))
162f579bf8eSKris Kennaway 			ext = sk_ASN1_TYPE_value(attr->value.set, 0);
163f579bf8eSKris Kennaway 		break;
164f579bf8eSKris Kennaway 		}
1656be8ae07SJacques Vidrine 	if(!ext || (ext->type != V_ASN1_SEQUENCE))
1666be8ae07SJacques Vidrine 		return NULL;
167f579bf8eSKris Kennaway 	p = ext->value.sequence->data;
168f579bf8eSKris Kennaway 	return d2i_ASN1_SET_OF_X509_EXTENSION(NULL, &p,
169f579bf8eSKris Kennaway 			ext->value.sequence->length,
170f579bf8eSKris Kennaway 			d2i_X509_EXTENSION, X509_EXTENSION_free,
171f579bf8eSKris Kennaway 			V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
172f579bf8eSKris Kennaway 	}
173f579bf8eSKris Kennaway 
174f579bf8eSKris Kennaway /* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
175f579bf8eSKris Kennaway  * in case we want to create a non standard one.
176f579bf8eSKris Kennaway  */
177f579bf8eSKris Kennaway 
178f579bf8eSKris Kennaway int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
179f579bf8eSKris Kennaway 				int nid)
180f579bf8eSKris Kennaway {
181f579bf8eSKris Kennaway 	unsigned char *p = NULL, *q;
182f579bf8eSKris Kennaway 	long len;
183f579bf8eSKris Kennaway 	ASN1_TYPE *at = NULL;
184f579bf8eSKris Kennaway 	X509_ATTRIBUTE *attr = NULL;
185f579bf8eSKris Kennaway 	if(!(at = ASN1_TYPE_new()) ||
186f579bf8eSKris Kennaway 		!(at->value.sequence = ASN1_STRING_new())) goto err;
187f579bf8eSKris Kennaway 
188f579bf8eSKris Kennaway 	at->type = V_ASN1_SEQUENCE;
189f579bf8eSKris Kennaway 	/* Generate encoding of extensions */
190f579bf8eSKris Kennaway 	len = i2d_ASN1_SET_OF_X509_EXTENSION(exts, NULL, i2d_X509_EXTENSION,
191f579bf8eSKris Kennaway 			V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE);
192ddd58736SKris Kennaway 	if(!(p = OPENSSL_malloc(len))) goto err;
193f579bf8eSKris Kennaway 	q = p;
194f579bf8eSKris Kennaway 	i2d_ASN1_SET_OF_X509_EXTENSION(exts, &q, i2d_X509_EXTENSION,
195f579bf8eSKris Kennaway 			V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE);
196f579bf8eSKris Kennaway 	at->value.sequence->data = p;
197f579bf8eSKris Kennaway 	p = NULL;
198f579bf8eSKris Kennaway 	at->value.sequence->length = len;
199f579bf8eSKris Kennaway 	if(!(attr = X509_ATTRIBUTE_new())) goto err;
200f579bf8eSKris Kennaway 	if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
201f579bf8eSKris Kennaway 	if(!sk_ASN1_TYPE_push(attr->value.set, at)) goto err;
202f579bf8eSKris Kennaway 	at = NULL;
2035c87c606SMark Murray 	attr->single = 0;
204f579bf8eSKris Kennaway 	attr->object = OBJ_nid2obj(nid);
205f579bf8eSKris Kennaway 	if(!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) goto err;
206f579bf8eSKris Kennaway 	return 1;
207f579bf8eSKris Kennaway 	err:
208ddd58736SKris Kennaway 	if(p) OPENSSL_free(p);
209f579bf8eSKris Kennaway 	X509_ATTRIBUTE_free(attr);
210f579bf8eSKris Kennaway 	ASN1_TYPE_free(at);
211f579bf8eSKris Kennaway 	return 0;
212f579bf8eSKris Kennaway }
213f579bf8eSKris Kennaway /* This is the normal usage: use the "official" OID */
214f579bf8eSKris Kennaway int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts)
215f579bf8eSKris Kennaway {
216f579bf8eSKris Kennaway 	return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
217f579bf8eSKris Kennaway }
218f579bf8eSKris Kennaway 
219f579bf8eSKris Kennaway /* Request attribute functions */
220f579bf8eSKris Kennaway 
221f579bf8eSKris Kennaway int X509_REQ_get_attr_count(const X509_REQ *req)
222f579bf8eSKris Kennaway {
223f579bf8eSKris Kennaway 	return X509at_get_attr_count(req->req_info->attributes);
224f579bf8eSKris Kennaway }
225f579bf8eSKris Kennaway 
226f579bf8eSKris Kennaway int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
227f579bf8eSKris Kennaway 			  int lastpos)
228f579bf8eSKris Kennaway {
229f579bf8eSKris Kennaway 	return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos);
230f579bf8eSKris Kennaway }
231f579bf8eSKris Kennaway 
232f579bf8eSKris Kennaway int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
233f579bf8eSKris Kennaway 			  int lastpos)
234f579bf8eSKris Kennaway {
235f579bf8eSKris Kennaway 	return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos);
236f579bf8eSKris Kennaway }
237f579bf8eSKris Kennaway 
238f579bf8eSKris Kennaway X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc)
239f579bf8eSKris Kennaway {
240f579bf8eSKris Kennaway 	return X509at_get_attr(req->req_info->attributes, loc);
241f579bf8eSKris Kennaway }
242f579bf8eSKris Kennaway 
243f579bf8eSKris Kennaway X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc)
244f579bf8eSKris Kennaway {
245f579bf8eSKris Kennaway 	return X509at_delete_attr(req->req_info->attributes, loc);
246f579bf8eSKris Kennaway }
247f579bf8eSKris Kennaway 
248f579bf8eSKris Kennaway int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr)
249f579bf8eSKris Kennaway {
250f579bf8eSKris Kennaway 	if(X509at_add1_attr(&req->req_info->attributes, attr)) return 1;
251f579bf8eSKris Kennaway 	return 0;
252f579bf8eSKris Kennaway }
253f579bf8eSKris Kennaway 
254f579bf8eSKris Kennaway int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
2555c87c606SMark Murray 			const ASN1_OBJECT *obj, int type,
2565c87c606SMark Murray 			const unsigned char *bytes, int len)
257f579bf8eSKris Kennaway {
258f579bf8eSKris Kennaway 	if(X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj,
259f579bf8eSKris Kennaway 				type, bytes, len)) return 1;
260f579bf8eSKris Kennaway 	return 0;
261f579bf8eSKris Kennaway }
262f579bf8eSKris Kennaway 
263f579bf8eSKris Kennaway int X509_REQ_add1_attr_by_NID(X509_REQ *req,
264f579bf8eSKris Kennaway 			int nid, int type,
2655c87c606SMark Murray 			const unsigned char *bytes, int len)
266f579bf8eSKris Kennaway {
267f579bf8eSKris Kennaway 	if(X509at_add1_attr_by_NID(&req->req_info->attributes, nid,
268f579bf8eSKris Kennaway 				type, bytes, len)) return 1;
269f579bf8eSKris Kennaway 	return 0;
270f579bf8eSKris Kennaway }
271f579bf8eSKris Kennaway 
272f579bf8eSKris Kennaway int X509_REQ_add1_attr_by_txt(X509_REQ *req,
2735c87c606SMark Murray 			const char *attrname, int type,
2745c87c606SMark Murray 			const unsigned char *bytes, int len)
275f579bf8eSKris Kennaway {
276f579bf8eSKris Kennaway 	if(X509at_add1_attr_by_txt(&req->req_info->attributes, attrname,
277f579bf8eSKris Kennaway 				type, bytes, len)) return 1;
278f579bf8eSKris Kennaway 	return 0;
279f579bf8eSKris Kennaway }
280