1 /* 2 * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include <openssl/bn.h> 13 #include <openssl/evp.h> 14 #include <openssl/asn1.h> 15 #include <openssl/asn1t.h> 16 #include <openssl/x509.h> 17 #include "crypto/x509.h" 18 #include <openssl/objects.h> 19 #include <openssl/buffer.h> 20 #include <openssl/pem.h> 21 22 X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) 23 { 24 X509_REQ *ret; 25 X509_REQ_INFO *ri; 26 int i; 27 EVP_PKEY *pktmp; 28 29 ret = X509_REQ_new(); 30 if (ret == NULL) { 31 X509err(X509_F_X509_TO_X509_REQ, ERR_R_MALLOC_FAILURE); 32 goto err; 33 } 34 35 ri = &ret->req_info; 36 37 ri->version->length = 1; 38 ri->version->data = OPENSSL_malloc(1); 39 if (ri->version->data == NULL) 40 goto err; 41 ri->version->data[0] = 0; /* version == 0 */ 42 43 if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x))) 44 goto err; 45 46 pktmp = X509_get0_pubkey(x); 47 if (pktmp == NULL) 48 goto err; 49 i = X509_REQ_set_pubkey(ret, pktmp); 50 if (!i) 51 goto err; 52 53 if (pkey != NULL) { 54 if (!X509_REQ_sign(ret, pkey, md)) 55 goto err; 56 } 57 return ret; 58 err: 59 X509_REQ_free(ret); 60 return NULL; 61 } 62 63 EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) 64 { 65 if (req == NULL) 66 return NULL; 67 return X509_PUBKEY_get(req->req_info.pubkey); 68 } 69 70 EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req) 71 { 72 if (req == NULL) 73 return NULL; 74 return X509_PUBKEY_get0(req->req_info.pubkey); 75 } 76 77 X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req) 78 { 79 return req->req_info.pubkey; 80 } 81 82 int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) 83 { 84 EVP_PKEY *xk = NULL; 85 int ok = 0; 86 87 xk = X509_REQ_get_pubkey(x); 88 switch (EVP_PKEY_cmp(xk, k)) { 89 case 1: 90 ok = 1; 91 break; 92 case 0: 93 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, 94 X509_R_KEY_VALUES_MISMATCH); 95 break; 96 case -1: 97 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH); 98 break; 99 case -2: 100 #ifndef OPENSSL_NO_EC 101 if (EVP_PKEY_id(k) == EVP_PKEY_EC) { 102 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB); 103 break; 104 } 105 #endif 106 #ifndef OPENSSL_NO_DH 107 if (EVP_PKEY_id(k) == EVP_PKEY_DH) { 108 /* No idea */ 109 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, 110 X509_R_CANT_CHECK_DH_KEY); 111 break; 112 } 113 #endif 114 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE); 115 } 116 117 EVP_PKEY_free(xk); 118 return ok; 119 } 120 121 /* 122 * It seems several organisations had the same idea of including a list of 123 * extensions in a certificate request. There are at least two OIDs that are 124 * used and there may be more: so the list is configurable. 125 */ 126 127 static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef }; 128 129 static int *ext_nids = ext_nid_list; 130 131 int X509_REQ_extension_nid(int req_nid) 132 { 133 int i, nid; 134 for (i = 0;; i++) { 135 nid = ext_nids[i]; 136 if (nid == NID_undef) 137 return 0; 138 else if (req_nid == nid) 139 return 1; 140 } 141 } 142 143 int *X509_REQ_get_extension_nids(void) 144 { 145 return ext_nids; 146 } 147 148 void X509_REQ_set_extension_nids(int *nids) 149 { 150 ext_nids = nids; 151 } 152 153 STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) 154 { 155 X509_ATTRIBUTE *attr; 156 ASN1_TYPE *ext = NULL; 157 int idx, *pnid; 158 const unsigned char *p; 159 160 if ((req == NULL) || !ext_nids) 161 return NULL; 162 for (pnid = ext_nids; *pnid != NID_undef; pnid++) { 163 idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); 164 if (idx == -1) 165 continue; 166 attr = X509_REQ_get_attr(req, idx); 167 ext = X509_ATTRIBUTE_get0_type(attr, 0); 168 break; 169 } 170 if (ext == NULL) /* no extensions is not an error */ 171 return sk_X509_EXTENSION_new_null(); 172 if (ext->type != V_ASN1_SEQUENCE) 173 return NULL; 174 p = ext->value.sequence->data; 175 return (STACK_OF(X509_EXTENSION) *) 176 ASN1_item_d2i(NULL, &p, ext->value.sequence->length, 177 ASN1_ITEM_rptr(X509_EXTENSIONS)); 178 } 179 180 /* 181 * Add a STACK_OF extensions to a certificate request: allow alternative OIDs 182 * in case we want to create a non standard one. 183 */ 184 185 int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, 186 int nid) 187 { 188 int extlen; 189 int rv = 0; 190 unsigned char *ext = NULL; 191 /* Generate encoding of extensions */ 192 extlen = ASN1_item_i2d((ASN1_VALUE *)exts, &ext, 193 ASN1_ITEM_rptr(X509_EXTENSIONS)); 194 if (extlen <= 0) 195 return 0; 196 rv = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, extlen); 197 OPENSSL_free(ext); 198 return rv; 199 } 200 201 /* This is the normal usage: use the "official" OID */ 202 int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) 203 { 204 return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); 205 } 206 207 /* Request attribute functions */ 208 209 int X509_REQ_get_attr_count(const X509_REQ *req) 210 { 211 return X509at_get_attr_count(req->req_info.attributes); 212 } 213 214 int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) 215 { 216 return X509at_get_attr_by_NID(req->req_info.attributes, nid, lastpos); 217 } 218 219 int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, 220 int lastpos) 221 { 222 return X509at_get_attr_by_OBJ(req->req_info.attributes, obj, lastpos); 223 } 224 225 X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) 226 { 227 return X509at_get_attr(req->req_info.attributes, loc); 228 } 229 230 X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) 231 { 232 X509_ATTRIBUTE *attr = X509at_delete_attr(req->req_info.attributes, loc); 233 234 if (attr != NULL) 235 req->req_info.enc.modified = 1; 236 return attr; 237 } 238 239 int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) 240 { 241 if (!X509at_add1_attr(&req->req_info.attributes, attr)) 242 return 0; 243 req->req_info.enc.modified = 1; 244 return 1; 245 } 246 247 int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, 248 const ASN1_OBJECT *obj, int type, 249 const unsigned char *bytes, int len) 250 { 251 if (!X509at_add1_attr_by_OBJ(&req->req_info.attributes, obj, 252 type, bytes, len)) 253 return 0; 254 req->req_info.enc.modified = 1; 255 return 1; 256 } 257 258 int X509_REQ_add1_attr_by_NID(X509_REQ *req, 259 int nid, int type, 260 const unsigned char *bytes, int len) 261 { 262 if (!X509at_add1_attr_by_NID(&req->req_info.attributes, nid, 263 type, bytes, len)) 264 return 0; 265 req->req_info.enc.modified = 1; 266 return 1; 267 } 268 269 int X509_REQ_add1_attr_by_txt(X509_REQ *req, 270 const char *attrname, int type, 271 const unsigned char *bytes, int len) 272 { 273 if (!X509at_add1_attr_by_txt(&req->req_info.attributes, attrname, 274 type, bytes, len)) 275 return 0; 276 req->req_info.enc.modified = 1; 277 return 1; 278 } 279 280 long X509_REQ_get_version(const X509_REQ *req) 281 { 282 return ASN1_INTEGER_get(req->req_info.version); 283 } 284 285 X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req) 286 { 287 return req->req_info.subject; 288 } 289 290 void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, 291 const X509_ALGOR **palg) 292 { 293 if (psig != NULL) 294 *psig = req->signature; 295 if (palg != NULL) 296 *palg = &req->sig_alg; 297 } 298 299 void X509_REQ_set0_signature(X509_REQ *req, ASN1_BIT_STRING *psig) 300 { 301 if (req->signature) 302 ASN1_BIT_STRING_free(req->signature); 303 req->signature = psig; 304 } 305 306 int X509_REQ_set1_signature_algo(X509_REQ *req, X509_ALGOR *palg) 307 { 308 return X509_ALGOR_copy(&req->sig_alg, palg); 309 } 310 311 int X509_REQ_get_signature_nid(const X509_REQ *req) 312 { 313 return OBJ_obj2nid(req->sig_alg.algorithm); 314 } 315 316 int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) 317 { 318 req->req_info.enc.modified = 1; 319 return i2d_X509_REQ_INFO(&req->req_info, pp); 320 } 321