xref: /openbsd/lib/libcrypto/asn1/x_req.c (revision f0d701e2)
1*f0d701e2Sbeck /* $OpenBSD: x_req.c,v 1.23 2024/07/08 14:48:49 beck Exp $ */
25b37fcf3Sryker /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
35b37fcf3Sryker  * All rights reserved.
45b37fcf3Sryker  *
55b37fcf3Sryker  * This package is an SSL implementation written
65b37fcf3Sryker  * by Eric Young (eay@cryptsoft.com).
75b37fcf3Sryker  * The implementation was written so as to conform with Netscapes SSL.
85b37fcf3Sryker  *
95b37fcf3Sryker  * This library is free for commercial and non-commercial use as long as
105b37fcf3Sryker  * the following conditions are aheared to.  The following conditions
115b37fcf3Sryker  * apply to all code found in this distribution, be it the RC4, RSA,
125b37fcf3Sryker  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
135b37fcf3Sryker  * included with this distribution is covered by the same copyright terms
145b37fcf3Sryker  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
155b37fcf3Sryker  *
165b37fcf3Sryker  * Copyright remains Eric Young's, and as such any Copyright notices in
175b37fcf3Sryker  * the code are not to be removed.
185b37fcf3Sryker  * If this package is used in a product, Eric Young should be given attribution
195b37fcf3Sryker  * as the author of the parts of the library used.
205b37fcf3Sryker  * This can be in the form of a textual message at program startup or
215b37fcf3Sryker  * in documentation (online or textual) provided with the package.
225b37fcf3Sryker  *
235b37fcf3Sryker  * Redistribution and use in source and binary forms, with or without
245b37fcf3Sryker  * modification, are permitted provided that the following conditions
255b37fcf3Sryker  * are met:
265b37fcf3Sryker  * 1. Redistributions of source code must retain the copyright
275b37fcf3Sryker  *    notice, this list of conditions and the following disclaimer.
285b37fcf3Sryker  * 2. Redistributions in binary form must reproduce the above copyright
295b37fcf3Sryker  *    notice, this list of conditions and the following disclaimer in the
305b37fcf3Sryker  *    documentation and/or other materials provided with the distribution.
315b37fcf3Sryker  * 3. All advertising materials mentioning features or use of this software
325b37fcf3Sryker  *    must display the following acknowledgement:
335b37fcf3Sryker  *    "This product includes cryptographic software written by
345b37fcf3Sryker  *     Eric Young (eay@cryptsoft.com)"
355b37fcf3Sryker  *    The word 'cryptographic' can be left out if the rouines from the library
365b37fcf3Sryker  *    being used are not cryptographic related :-).
375b37fcf3Sryker  * 4. If you include any Windows specific code (or a derivative thereof) from
385b37fcf3Sryker  *    the apps directory (application code) you must include an acknowledgement:
395b37fcf3Sryker  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
405b37fcf3Sryker  *
415b37fcf3Sryker  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
425b37fcf3Sryker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
435b37fcf3Sryker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
445b37fcf3Sryker  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
455b37fcf3Sryker  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
465b37fcf3Sryker  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
475b37fcf3Sryker  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
485b37fcf3Sryker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
495b37fcf3Sryker  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
505b37fcf3Sryker  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
515b37fcf3Sryker  * SUCH DAMAGE.
525b37fcf3Sryker  *
535b37fcf3Sryker  * The licence and distribution terms for any publically available version or
545b37fcf3Sryker  * derivative of this code cannot be changed.  i.e. this code cannot simply be
555b37fcf3Sryker  * copied and put under another distribution licence
565b37fcf3Sryker  * [including the GNU Public Licence.]
575b37fcf3Sryker  */
585b37fcf3Sryker 
595b37fcf3Sryker #include <stdio.h>
60b6ab114eSjsing 
61da347917Sbeck #include <openssl/asn1t.h>
62913ec974Sbeck #include <openssl/x509.h>
635b37fcf3Sryker 
64c9675a23Stb #include "x509_local.h"
65838f0b6dStb 
66da347917Sbeck /* X509_REQ_INFO is handled in an unusual way to get round
67da347917Sbeck  * invalid encodings. Some broken certificate requests don't
68da347917Sbeck  * encode the attributes field if it is empty. This is in
69da347917Sbeck  * violation of PKCS#10 but we need to tolerate it. We do
70da347917Sbeck  * this by making the attributes field OPTIONAL then using
71da347917Sbeck  * the callback to initialise it to an empty STACK.
72da347917Sbeck  *
73da347917Sbeck  * This means that the field will be correctly encoded unless
74da347917Sbeck  * we NULL out the field.
75da347917Sbeck  *
76da347917Sbeck  * As a result we no longer need the req_kludge field because
77da347917Sbeck  * the information is now contained in the attributes field:
78da347917Sbeck  * 1. If it is NULL then it's the invalid omission.
79da347917Sbeck  * 2. If it is empty it is the correct encoding.
80da347917Sbeck  * 3. If it is not empty then some attributes are present.
81da347917Sbeck  *
825b37fcf3Sryker  */
83da347917Sbeck 
84a787b3faSjsing static int
rinf_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it,void * exarg)85a787b3faSjsing rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
865b37fcf3Sryker {
87da347917Sbeck 	X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
88da347917Sbeck 
89da347917Sbeck 	if (operation == ASN1_OP_NEW_POST) {
90da347917Sbeck 		rinf->attributes = sk_X509_ATTRIBUTE_new_null();
91a787b3faSjsing 		if (!rinf->attributes)
92a787b3faSjsing 			return 0;
935b37fcf3Sryker 	}
94da347917Sbeck 	return 1;
955b37fcf3Sryker }
965b37fcf3Sryker 
972c25b402Sjsing static const ASN1_AUX X509_REQ_INFO_aux = {
982c25b402Sjsing 	.flags = ASN1_AFLG_ENCODING,
992c25b402Sjsing 	.asn1_cb = rinf_cb,
1002c25b402Sjsing 	.enc_offset = offsetof(X509_REQ_INFO, enc),
1012c25b402Sjsing };
1022c25b402Sjsing static const ASN1_TEMPLATE X509_REQ_INFO_seq_tt[] = {
1032c25b402Sjsing 	{
1042c25b402Sjsing 		.offset = offsetof(X509_REQ_INFO, version),
1052c25b402Sjsing 		.field_name = "version",
1062c25b402Sjsing 		.item = &ASN1_INTEGER_it,
1072c25b402Sjsing 	},
1082c25b402Sjsing 	{
1092c25b402Sjsing 		.offset = offsetof(X509_REQ_INFO, subject),
1102c25b402Sjsing 		.field_name = "subject",
1112c25b402Sjsing 		.item = &X509_NAME_it,
1122c25b402Sjsing 	},
1132c25b402Sjsing 	{
1142c25b402Sjsing 		.offset = offsetof(X509_REQ_INFO, pubkey),
1152c25b402Sjsing 		.field_name = "pubkey",
1162c25b402Sjsing 		.item = &X509_PUBKEY_it,
1172c25b402Sjsing 	},
118da347917Sbeck 	/* This isn't really OPTIONAL but it gets round invalid
119da347917Sbeck 	 * encodings
1205b37fcf3Sryker 	 */
1212c25b402Sjsing 	{
1222c25b402Sjsing 		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
1232c25b402Sjsing 		.offset = offsetof(X509_REQ_INFO, attributes),
1242c25b402Sjsing 		.field_name = "attributes",
1252c25b402Sjsing 		.item = &X509_ATTRIBUTE_it,
1262c25b402Sjsing 	},
1272c25b402Sjsing };
1282c25b402Sjsing 
1292c25b402Sjsing const ASN1_ITEM X509_REQ_INFO_it = {
1302c25b402Sjsing 	.itype = ASN1_ITYPE_SEQUENCE,
1312c25b402Sjsing 	.utype = V_ASN1_SEQUENCE,
1322c25b402Sjsing 	.templates = X509_REQ_INFO_seq_tt,
1332c25b402Sjsing 	.tcount = sizeof(X509_REQ_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
1342c25b402Sjsing 	.funcs = &X509_REQ_INFO_aux,
1352c25b402Sjsing 	.size = sizeof(X509_REQ_INFO),
1362c25b402Sjsing 	.sname = "X509_REQ_INFO",
1372c25b402Sjsing };
138*f0d701e2Sbeck LCRYPTO_ALIAS(X509_REQ_INFO_it);
1395b37fcf3Sryker 
140811ee5a3Sjsing 
141811ee5a3Sjsing X509_REQ_INFO *
d2i_X509_REQ_INFO(X509_REQ_INFO ** a,const unsigned char ** in,long len)142811ee5a3Sjsing d2i_X509_REQ_INFO(X509_REQ_INFO **a, const unsigned char **in, long len)
143811ee5a3Sjsing {
144811ee5a3Sjsing 	return (X509_REQ_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
145811ee5a3Sjsing 	    &X509_REQ_INFO_it);
146811ee5a3Sjsing }
147e1608179Sbeck LCRYPTO_ALIAS(d2i_X509_REQ_INFO);
148811ee5a3Sjsing 
149811ee5a3Sjsing int
i2d_X509_REQ_INFO(X509_REQ_INFO * a,unsigned char ** out)150811ee5a3Sjsing i2d_X509_REQ_INFO(X509_REQ_INFO *a, unsigned char **out)
151811ee5a3Sjsing {
152811ee5a3Sjsing 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_REQ_INFO_it);
153811ee5a3Sjsing }
154e1608179Sbeck LCRYPTO_ALIAS(i2d_X509_REQ_INFO);
155811ee5a3Sjsing 
156811ee5a3Sjsing X509_REQ_INFO *
X509_REQ_INFO_new(void)157811ee5a3Sjsing X509_REQ_INFO_new(void)
158811ee5a3Sjsing {
159811ee5a3Sjsing 	return (X509_REQ_INFO *)ASN1_item_new(&X509_REQ_INFO_it);
160811ee5a3Sjsing }
161e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_INFO_new);
162811ee5a3Sjsing 
163811ee5a3Sjsing void
X509_REQ_INFO_free(X509_REQ_INFO * a)164811ee5a3Sjsing X509_REQ_INFO_free(X509_REQ_INFO *a)
165811ee5a3Sjsing {
166811ee5a3Sjsing 	ASN1_item_free((ASN1_VALUE *)a, &X509_REQ_INFO_it);
167811ee5a3Sjsing }
168e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_INFO_free);
1695b37fcf3Sryker 
1702c25b402Sjsing static const ASN1_AUX X509_REQ_aux = {
1712c25b402Sjsing 	.app_data = NULL,
1722c25b402Sjsing 	.flags = ASN1_AFLG_REFCOUNT,
1732c25b402Sjsing 	.ref_offset = offsetof(X509_REQ, references),
1742c25b402Sjsing 	.ref_lock = CRYPTO_LOCK_X509_REQ,
1752c25b402Sjsing };
1762c25b402Sjsing static const ASN1_TEMPLATE X509_REQ_seq_tt[] = {
1772c25b402Sjsing 	{
1782c25b402Sjsing 		.offset = offsetof(X509_REQ, req_info),
1792c25b402Sjsing 		.field_name = "req_info",
1802c25b402Sjsing 		.item = &X509_REQ_INFO_it,
1812c25b402Sjsing 	},
1822c25b402Sjsing 	{
1832c25b402Sjsing 		.offset = offsetof(X509_REQ, sig_alg),
1842c25b402Sjsing 		.field_name = "sig_alg",
1852c25b402Sjsing 		.item = &X509_ALGOR_it,
1862c25b402Sjsing 	},
1872c25b402Sjsing 	{
1882c25b402Sjsing 		.offset = offsetof(X509_REQ, signature),
1892c25b402Sjsing 		.field_name = "signature",
1902c25b402Sjsing 		.item = &ASN1_BIT_STRING_it,
1912c25b402Sjsing 	},
1922c25b402Sjsing };
1932c25b402Sjsing 
1942c25b402Sjsing const ASN1_ITEM X509_REQ_it = {
1952c25b402Sjsing 	.itype = ASN1_ITYPE_SEQUENCE,
1962c25b402Sjsing 	.utype = V_ASN1_SEQUENCE,
1972c25b402Sjsing 	.templates = X509_REQ_seq_tt,
1982c25b402Sjsing 	.tcount = sizeof(X509_REQ_seq_tt) / sizeof(ASN1_TEMPLATE),
1992c25b402Sjsing 	.funcs = &X509_REQ_aux,
2002c25b402Sjsing 	.size = sizeof(X509_REQ),
2012c25b402Sjsing 	.sname = "X509_REQ",
2022c25b402Sjsing };
203*f0d701e2Sbeck LCRYPTO_ALIAS(X509_REQ_it);
2045b37fcf3Sryker 
205811ee5a3Sjsing 
206811ee5a3Sjsing X509_REQ *
d2i_X509_REQ(X509_REQ ** a,const unsigned char ** in,long len)207811ee5a3Sjsing d2i_X509_REQ(X509_REQ **a, const unsigned char **in, long len)
208811ee5a3Sjsing {
209811ee5a3Sjsing 	return (X509_REQ *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
210811ee5a3Sjsing 	    &X509_REQ_it);
211811ee5a3Sjsing }
212e1608179Sbeck LCRYPTO_ALIAS(d2i_X509_REQ);
213811ee5a3Sjsing 
214811ee5a3Sjsing int
i2d_X509_REQ(X509_REQ * a,unsigned char ** out)215811ee5a3Sjsing i2d_X509_REQ(X509_REQ *a, unsigned char **out)
216811ee5a3Sjsing {
217811ee5a3Sjsing 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_REQ_it);
218811ee5a3Sjsing }
219e1608179Sbeck LCRYPTO_ALIAS(i2d_X509_REQ);
220811ee5a3Sjsing 
221811ee5a3Sjsing X509_REQ *
X509_REQ_new(void)222811ee5a3Sjsing X509_REQ_new(void)
223811ee5a3Sjsing {
224811ee5a3Sjsing 	return (X509_REQ *)ASN1_item_new(&X509_REQ_it);
225811ee5a3Sjsing }
226e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_new);
227811ee5a3Sjsing 
228811ee5a3Sjsing void
X509_REQ_free(X509_REQ * a)229811ee5a3Sjsing X509_REQ_free(X509_REQ *a)
230811ee5a3Sjsing {
231811ee5a3Sjsing 	ASN1_item_free((ASN1_VALUE *)a, &X509_REQ_it);
232811ee5a3Sjsing }
233e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_free);
2345cfcf2a1Sjsing 
2355cfcf2a1Sjsing X509_REQ *
X509_REQ_dup(X509_REQ * x)2365cfcf2a1Sjsing X509_REQ_dup(X509_REQ *x)
2375cfcf2a1Sjsing {
238589a2d47Sjsing 	return ASN1_item_dup(&X509_REQ_it, x);
2395cfcf2a1Sjsing }
240e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_dup);
2412b65c176Sjsing 
242d8b3f393Sjsing int
X509_REQ_get_signature_nid(const X509_REQ * req)243d8b3f393Sjsing X509_REQ_get_signature_nid(const X509_REQ *req)
244d8b3f393Sjsing {
245d8b3f393Sjsing 	return OBJ_obj2nid(req->sig_alg->algorithm);
246d8b3f393Sjsing }
247e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_get_signature_nid);
248d8b3f393Sjsing 
2492b65c176Sjsing void
X509_REQ_get0_signature(const X509_REQ * req,const ASN1_BIT_STRING ** psig,const X509_ALGOR ** palg)2502b65c176Sjsing X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig,
2512b65c176Sjsing     const X509_ALGOR **palg)
2522b65c176Sjsing {
2532b65c176Sjsing 	if (psig != NULL)
2542b65c176Sjsing 		*psig = req->signature;
2552b65c176Sjsing 	if (palg != NULL)
2562b65c176Sjsing 		*palg = req->sig_alg;
2572b65c176Sjsing }
258e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_get0_signature);
259