1 /* 2 * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (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_ex(x->libctx, x->propq); 30 if (ret == NULL) { 31 ERR_raise(ERR_LIB_X509, 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_eq(xk, k)) { 89 case 1: 90 ok = 1; 91 break; 92 case 0: 93 ERR_raise(ERR_LIB_X509, X509_R_KEY_VALUES_MISMATCH); 94 break; 95 case -1: 96 ERR_raise(ERR_LIB_X509, X509_R_KEY_TYPE_MISMATCH); 97 break; 98 case -2: 99 ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_KEY_TYPE); 100 } 101 102 EVP_PKEY_free(xk); 103 return ok; 104 } 105 106 /* 107 * It seems several organisations had the same idea of including a list of 108 * extensions in a certificate request. There are at least two OIDs that are 109 * used and there may be more: so the list is configurable. 110 */ 111 112 static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef }; 113 114 static int *ext_nids = ext_nid_list; 115 116 int X509_REQ_extension_nid(int req_nid) 117 { 118 int i, nid; 119 120 for (i = 0;; i++) { 121 nid = ext_nids[i]; 122 if (nid == NID_undef) 123 return 0; 124 else if (req_nid == nid) 125 return 1; 126 } 127 } 128 129 int *X509_REQ_get_extension_nids(void) 130 { 131 return ext_nids; 132 } 133 134 void X509_REQ_set_extension_nids(int *nids) 135 { 136 ext_nids = nids; 137 } 138 139 STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) 140 { 141 X509_ATTRIBUTE *attr; 142 ASN1_TYPE *ext = NULL; 143 int idx, *pnid; 144 const unsigned char *p; 145 146 if (req == NULL || !ext_nids) 147 return NULL; 148 for (pnid = ext_nids; *pnid != NID_undef; pnid++) { 149 idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); 150 if (idx == -1) 151 continue; 152 attr = X509_REQ_get_attr(req, idx); 153 ext = X509_ATTRIBUTE_get0_type(attr, 0); 154 break; 155 } 156 if (ext == NULL) /* no extensions is not an error */ 157 return sk_X509_EXTENSION_new_null(); 158 if (ext->type != V_ASN1_SEQUENCE) 159 return NULL; 160 p = ext->value.sequence->data; 161 return (STACK_OF(X509_EXTENSION) *) 162 ASN1_item_d2i(NULL, &p, ext->value.sequence->length, 163 ASN1_ITEM_rptr(X509_EXTENSIONS)); 164 } 165 166 /* 167 * Add a STACK_OF extensions to a certificate request: allow alternative OIDs 168 * in case we want to create a non standard one. 169 */ 170 int X509_REQ_add_extensions_nid(X509_REQ *req, 171 const STACK_OF(X509_EXTENSION) *exts, int nid) 172 { 173 int extlen; 174 int rv = 0; 175 unsigned char *ext = NULL; 176 177 /* Generate encoding of extensions */ 178 extlen = ASN1_item_i2d((const ASN1_VALUE *)exts, &ext, 179 ASN1_ITEM_rptr(X509_EXTENSIONS)); 180 if (extlen <= 0) 181 return 0; 182 rv = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, extlen); 183 OPENSSL_free(ext); 184 return rv; 185 } 186 187 /* This is the normal usage: use the "official" OID */ 188 int X509_REQ_add_extensions(X509_REQ *req, const STACK_OF(X509_EXTENSION) *exts) 189 { 190 return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); 191 } 192 193 /* Request attribute functions */ 194 195 int X509_REQ_get_attr_count(const X509_REQ *req) 196 { 197 return X509at_get_attr_count(req->req_info.attributes); 198 } 199 200 int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) 201 { 202 return X509at_get_attr_by_NID(req->req_info.attributes, nid, lastpos); 203 } 204 205 int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, 206 int lastpos) 207 { 208 return X509at_get_attr_by_OBJ(req->req_info.attributes, obj, lastpos); 209 } 210 211 X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) 212 { 213 return X509at_get_attr(req->req_info.attributes, loc); 214 } 215 216 X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) 217 { 218 X509_ATTRIBUTE *attr; 219 220 if (req == NULL) { 221 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 222 return 0; 223 } 224 attr = X509at_delete_attr(req->req_info.attributes, loc); 225 if (attr != NULL) 226 req->req_info.enc.modified = 1; 227 return attr; 228 } 229 230 int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) 231 { 232 if (req == NULL) { 233 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 234 return 0; 235 } 236 if (!X509at_add1_attr(&req->req_info.attributes, attr)) 237 return 0; 238 req->req_info.enc.modified = 1; 239 return 1; 240 } 241 242 int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, 243 const ASN1_OBJECT *obj, int type, 244 const unsigned char *bytes, int len) 245 { 246 if (req == NULL) { 247 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 248 return 0; 249 } 250 if (!X509at_add1_attr_by_OBJ(&req->req_info.attributes, obj, 251 type, bytes, len)) 252 return 0; 253 req->req_info.enc.modified = 1; 254 return 1; 255 } 256 257 int X509_REQ_add1_attr_by_NID(X509_REQ *req, 258 int nid, int type, 259 const unsigned char *bytes, int len) 260 { 261 if (req == NULL) { 262 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 263 return 0; 264 } 265 if (!X509at_add1_attr_by_NID(&req->req_info.attributes, nid, 266 type, bytes, len)) 267 return 0; 268 req->req_info.enc.modified = 1; 269 return 1; 270 } 271 272 int X509_REQ_add1_attr_by_txt(X509_REQ *req, 273 const char *attrname, int type, 274 const unsigned char *bytes, int len) 275 { 276 if (req == NULL) { 277 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 278 return 0; 279 } 280 if (!X509at_add1_attr_by_txt(&req->req_info.attributes, attrname, 281 type, bytes, len)) 282 return 0; 283 req->req_info.enc.modified = 1; 284 return 1; 285 } 286 287 long X509_REQ_get_version(const X509_REQ *req) 288 { 289 return ASN1_INTEGER_get(req->req_info.version); 290 } 291 292 X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req) 293 { 294 return req->req_info.subject; 295 } 296 297 void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, 298 const X509_ALGOR **palg) 299 { 300 if (psig != NULL) 301 *psig = req->signature; 302 if (palg != NULL) 303 *palg = &req->sig_alg; 304 } 305 306 void X509_REQ_set0_signature(X509_REQ *req, ASN1_BIT_STRING *psig) 307 { 308 if (req->signature) 309 ASN1_BIT_STRING_free(req->signature); 310 req->signature = psig; 311 } 312 313 int X509_REQ_set1_signature_algo(X509_REQ *req, X509_ALGOR *palg) 314 { 315 return X509_ALGOR_copy(&req->sig_alg, palg); 316 } 317 318 int X509_REQ_get_signature_nid(const X509_REQ *req) 319 { 320 return OBJ_obj2nid(req->sig_alg.algorithm); 321 } 322 323 int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) 324 { 325 if (req == NULL) { 326 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 327 return 0; 328 } 329 req->req_info.enc.modified = 1; 330 return i2d_X509_REQ_INFO(&req->req_info, pp); 331 } 332