1*e1608179Sbeck /* $OpenBSD: x_req.c,v 1.22 2024/04/09 13:55:02 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 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 }; 1385b37fcf3Sryker 139811ee5a3Sjsing 140811ee5a3Sjsing X509_REQ_INFO * 141811ee5a3Sjsing d2i_X509_REQ_INFO(X509_REQ_INFO **a, const unsigned char **in, long len) 142811ee5a3Sjsing { 143811ee5a3Sjsing return (X509_REQ_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 144811ee5a3Sjsing &X509_REQ_INFO_it); 145811ee5a3Sjsing } 146*e1608179Sbeck LCRYPTO_ALIAS(d2i_X509_REQ_INFO); 147811ee5a3Sjsing 148811ee5a3Sjsing int 149811ee5a3Sjsing i2d_X509_REQ_INFO(X509_REQ_INFO *a, unsigned char **out) 150811ee5a3Sjsing { 151811ee5a3Sjsing return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_REQ_INFO_it); 152811ee5a3Sjsing } 153*e1608179Sbeck LCRYPTO_ALIAS(i2d_X509_REQ_INFO); 154811ee5a3Sjsing 155811ee5a3Sjsing X509_REQ_INFO * 156811ee5a3Sjsing X509_REQ_INFO_new(void) 157811ee5a3Sjsing { 158811ee5a3Sjsing return (X509_REQ_INFO *)ASN1_item_new(&X509_REQ_INFO_it); 159811ee5a3Sjsing } 160*e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_INFO_new); 161811ee5a3Sjsing 162811ee5a3Sjsing void 163811ee5a3Sjsing X509_REQ_INFO_free(X509_REQ_INFO *a) 164811ee5a3Sjsing { 165811ee5a3Sjsing ASN1_item_free((ASN1_VALUE *)a, &X509_REQ_INFO_it); 166811ee5a3Sjsing } 167*e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_INFO_free); 1685b37fcf3Sryker 1692c25b402Sjsing static const ASN1_AUX X509_REQ_aux = { 1702c25b402Sjsing .app_data = NULL, 1712c25b402Sjsing .flags = ASN1_AFLG_REFCOUNT, 1722c25b402Sjsing .ref_offset = offsetof(X509_REQ, references), 1732c25b402Sjsing .ref_lock = CRYPTO_LOCK_X509_REQ, 1742c25b402Sjsing }; 1752c25b402Sjsing static const ASN1_TEMPLATE X509_REQ_seq_tt[] = { 1762c25b402Sjsing { 1772c25b402Sjsing .offset = offsetof(X509_REQ, req_info), 1782c25b402Sjsing .field_name = "req_info", 1792c25b402Sjsing .item = &X509_REQ_INFO_it, 1802c25b402Sjsing }, 1812c25b402Sjsing { 1822c25b402Sjsing .offset = offsetof(X509_REQ, sig_alg), 1832c25b402Sjsing .field_name = "sig_alg", 1842c25b402Sjsing .item = &X509_ALGOR_it, 1852c25b402Sjsing }, 1862c25b402Sjsing { 1872c25b402Sjsing .offset = offsetof(X509_REQ, signature), 1882c25b402Sjsing .field_name = "signature", 1892c25b402Sjsing .item = &ASN1_BIT_STRING_it, 1902c25b402Sjsing }, 1912c25b402Sjsing }; 1922c25b402Sjsing 1932c25b402Sjsing const ASN1_ITEM X509_REQ_it = { 1942c25b402Sjsing .itype = ASN1_ITYPE_SEQUENCE, 1952c25b402Sjsing .utype = V_ASN1_SEQUENCE, 1962c25b402Sjsing .templates = X509_REQ_seq_tt, 1972c25b402Sjsing .tcount = sizeof(X509_REQ_seq_tt) / sizeof(ASN1_TEMPLATE), 1982c25b402Sjsing .funcs = &X509_REQ_aux, 1992c25b402Sjsing .size = sizeof(X509_REQ), 2002c25b402Sjsing .sname = "X509_REQ", 2012c25b402Sjsing }; 2025b37fcf3Sryker 203811ee5a3Sjsing 204811ee5a3Sjsing X509_REQ * 205811ee5a3Sjsing d2i_X509_REQ(X509_REQ **a, const unsigned char **in, long len) 206811ee5a3Sjsing { 207811ee5a3Sjsing return (X509_REQ *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 208811ee5a3Sjsing &X509_REQ_it); 209811ee5a3Sjsing } 210*e1608179Sbeck LCRYPTO_ALIAS(d2i_X509_REQ); 211811ee5a3Sjsing 212811ee5a3Sjsing int 213811ee5a3Sjsing i2d_X509_REQ(X509_REQ *a, unsigned char **out) 214811ee5a3Sjsing { 215811ee5a3Sjsing return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_REQ_it); 216811ee5a3Sjsing } 217*e1608179Sbeck LCRYPTO_ALIAS(i2d_X509_REQ); 218811ee5a3Sjsing 219811ee5a3Sjsing X509_REQ * 220811ee5a3Sjsing X509_REQ_new(void) 221811ee5a3Sjsing { 222811ee5a3Sjsing return (X509_REQ *)ASN1_item_new(&X509_REQ_it); 223811ee5a3Sjsing } 224*e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_new); 225811ee5a3Sjsing 226811ee5a3Sjsing void 227811ee5a3Sjsing X509_REQ_free(X509_REQ *a) 228811ee5a3Sjsing { 229811ee5a3Sjsing ASN1_item_free((ASN1_VALUE *)a, &X509_REQ_it); 230811ee5a3Sjsing } 231*e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_free); 2325cfcf2a1Sjsing 2335cfcf2a1Sjsing X509_REQ * 2345cfcf2a1Sjsing X509_REQ_dup(X509_REQ *x) 2355cfcf2a1Sjsing { 236589a2d47Sjsing return ASN1_item_dup(&X509_REQ_it, x); 2375cfcf2a1Sjsing } 238*e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_dup); 2392b65c176Sjsing 240d8b3f393Sjsing int 241d8b3f393Sjsing X509_REQ_get_signature_nid(const X509_REQ *req) 242d8b3f393Sjsing { 243d8b3f393Sjsing return OBJ_obj2nid(req->sig_alg->algorithm); 244d8b3f393Sjsing } 245*e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_get_signature_nid); 246d8b3f393Sjsing 2472b65c176Sjsing void 2482b65c176Sjsing X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, 2492b65c176Sjsing const X509_ALGOR **palg) 2502b65c176Sjsing { 2512b65c176Sjsing if (psig != NULL) 2522b65c176Sjsing *psig = req->signature; 2532b65c176Sjsing if (palg != NULL) 2542b65c176Sjsing *palg = req->sig_alg; 2552b65c176Sjsing } 256*e1608179Sbeck LCRYPTO_ALIAS(X509_REQ_get0_signature); 257