1 /* 2 * Copyright 1995-2016 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 "internal/x509_int.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 || (ext->type != V_ASN1_SEQUENCE)) 171 return NULL; 172 p = ext->value.sequence->data; 173 return (STACK_OF(X509_EXTENSION) *) 174 ASN1_item_d2i(NULL, &p, ext->value.sequence->length, 175 ASN1_ITEM_rptr(X509_EXTENSIONS)); 176 } 177 178 /* 179 * Add a STACK_OF extensions to a certificate request: allow alternative OIDs 180 * in case we want to create a non standard one. 181 */ 182 183 int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, 184 int nid) 185 { 186 int extlen; 187 int rv = 0; 188 unsigned char *ext = NULL; 189 /* Generate encoding of extensions */ 190 extlen = ASN1_item_i2d((ASN1_VALUE *)exts, &ext, 191 ASN1_ITEM_rptr(X509_EXTENSIONS)); 192 if (extlen <= 0) 193 return 0; 194 rv = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, extlen); 195 OPENSSL_free(ext); 196 return rv; 197 } 198 199 /* This is the normal usage: use the "official" OID */ 200 int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) 201 { 202 return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); 203 } 204 205 /* Request attribute functions */ 206 207 int X509_REQ_get_attr_count(const X509_REQ *req) 208 { 209 return X509at_get_attr_count(req->req_info.attributes); 210 } 211 212 int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) 213 { 214 return X509at_get_attr_by_NID(req->req_info.attributes, nid, lastpos); 215 } 216 217 int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, 218 int lastpos) 219 { 220 return X509at_get_attr_by_OBJ(req->req_info.attributes, obj, lastpos); 221 } 222 223 X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) 224 { 225 return X509at_get_attr(req->req_info.attributes, loc); 226 } 227 228 X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) 229 { 230 return X509at_delete_attr(req->req_info.attributes, loc); 231 } 232 233 int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) 234 { 235 if (X509at_add1_attr(&req->req_info.attributes, attr)) 236 return 1; 237 return 0; 238 } 239 240 int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, 241 const ASN1_OBJECT *obj, int type, 242 const unsigned char *bytes, int len) 243 { 244 if (X509at_add1_attr_by_OBJ(&req->req_info.attributes, obj, 245 type, bytes, len)) 246 return 1; 247 return 0; 248 } 249 250 int X509_REQ_add1_attr_by_NID(X509_REQ *req, 251 int nid, int type, 252 const unsigned char *bytes, int len) 253 { 254 if (X509at_add1_attr_by_NID(&req->req_info.attributes, nid, 255 type, bytes, len)) 256 return 1; 257 return 0; 258 } 259 260 int X509_REQ_add1_attr_by_txt(X509_REQ *req, 261 const char *attrname, int type, 262 const unsigned char *bytes, int len) 263 { 264 if (X509at_add1_attr_by_txt(&req->req_info.attributes, attrname, 265 type, bytes, len)) 266 return 1; 267 return 0; 268 } 269 270 long X509_REQ_get_version(const X509_REQ *req) 271 { 272 return ASN1_INTEGER_get(req->req_info.version); 273 } 274 275 X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req) 276 { 277 return req->req_info.subject; 278 } 279 280 void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, 281 const X509_ALGOR **palg) 282 { 283 if (psig != NULL) 284 *psig = req->signature; 285 if (palg != NULL) 286 *palg = &req->sig_alg; 287 } 288 289 int X509_REQ_get_signature_nid(const X509_REQ *req) 290 { 291 return OBJ_obj2nid(req->sig_alg.algorithm); 292 } 293 294 int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) 295 { 296 req->req_info.enc.modified = 1; 297 return i2d_X509_REQ_INFO(&req->req_info, pp); 298 } 299