2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
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
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>
22 X509_REQ
*X509_to_X509_REQ(X509
*x
, EVP_PKEY
*pkey
, const EVP_MD
*md
)
29 ret
= X509_REQ_new_ex(x
->libctx
, x
->propq
);
31 ERR_raise(ERR_LIB_X509
, ERR_R_MALLOC_FAILURE
);
37 ri
->version
->length
= 1;
38 ri
->version
->data
= OPENSSL_malloc(1);
39 if (ri
->version
->data
== NULL
)
41 ri
->version
->data
[0] = 0; /* version == 0 */
43 if (!X509_REQ_set_subject_name(ret
, X509_get_subject_name(x
)))
46 pktmp
= X509_get0_pubkey(x
);
49 i
= X509_REQ_set_pubkey(ret
, pktmp
);
54 if (!X509_REQ_sign(ret
, pkey
, md
))
63 EVP_PKEY
*X509_REQ_get_pubkey(X509_REQ
*req
)
67 return X509_PUBKEY_get(req
->req_info
.pubkey
);
70 EVP_PKEY
*X509_REQ_get0_pubkey(X509_REQ
*req
)
74 return X509_PUBKEY_get0(req
->req_info
.pubkey
);
77 X509_PUBKEY
*X509_REQ_get_X509_PUBKEY(X509_REQ
*req
)
79 return req
->req_info
.pubkey
;
82 int X509_REQ_check_private_key(X509_REQ
*x
, EVP_PKEY
*k
)
87 xk
= X509_REQ_get_pubkey(x
);
88 switch (EVP_PKEY_eq(xk
, k
)) {
93 ERR_raise(ERR_LIB_X509
, X509_R_KEY_VALUES_MISMATCH
);
96 ERR_raise(ERR_LIB_X509
, X509_R_KEY_TYPE_MISMATCH
);
99 ERR_raise(ERR_LIB_X509
, X509_R_UNKNOWN_KEY_TYPE
);
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.
112 static int ext_nid_list
[] = { NID_ext_req
, NID_ms_ext_req
, NID_undef
};
114 static int *ext_nids
= ext_nid_list
;
116 int X509_REQ_extension_nid(int req_nid
)
121 if (nid
== NID_undef
)
123 else if (req_nid
== nid
)
128 int *X509_REQ_get_extension_nids(void)
133 void X509_REQ_set_extension_nids(int *nids
)
138 STACK_OF(X509_EXTENSION
) *X509_REQ_get_extensions(X509_REQ
*req
)
140 X509_ATTRIBUTE
*attr
;
141 ASN1_TYPE
*ext
= NULL
;
143 const unsigned char *p
;
145 if ((req
== NULL
) || !ext_nids
)
147 for (pnid
= ext_nids
; *pnid
!= NID_undef
; pnid
++) {
148 idx
= X509_REQ_get_attr_by_NID(req
, *pnid
, -1);
151 attr
= X509_REQ_get_attr(req
, idx
);
152 ext
= X509_ATTRIBUTE_get0_type(attr
, 0);
155 if (ext
== NULL
) /* no extensions is not an error */
156 return sk_X509_EXTENSION_new_null();
157 if (ext
->type
!= V_ASN1_SEQUENCE
) {
158 ERR_raise(ERR_LIB_X509
, X509_R_WRONG_TYPE
);
161 p
= ext
->value
.sequence
->data
;
162 return (STACK_OF(X509_EXTENSION
) *)
163 ASN1_item_d2i(NULL
, &p
, ext
->value
.sequence
->length
,
164 ASN1_ITEM_rptr(X509_EXTENSIONS
));
168 * Add a STACK_OF extensions to a certificate request: allow alternative OIDs
169 * in case we want to create a non standard one.
171 int X509_REQ_add_extensions_nid(X509_REQ
*req
,
172 const STACK_OF(X509_EXTENSION
) *exts
, int nid
)
176 unsigned char *ext
= NULL
;
178 /* Generate encoding of extensions */
179 extlen
= ASN1_item_i2d((const ASN1_VALUE
*)exts
, &ext
,
180 ASN1_ITEM_rptr(X509_EXTENSIONS
));
183 rv
= X509_REQ_add1_attr_by_NID(req
, nid
, V_ASN1_SEQUENCE
, ext
, extlen
);
188 /* This is the normal usage: use the "official" OID */
189 int X509_REQ_add_extensions(X509_REQ
*req
, const STACK_OF(X509_EXTENSION
) *exts
)
191 return X509_REQ_add_extensions_nid(req
, exts
, NID_ext_req
);
194 /* Request attribute functions */
196 int X509_REQ_get_attr_count(const X509_REQ
*req
)
198 return X509at_get_attr_count(req
->req_info
.attributes
);
201 int X509_REQ_get_attr_by_NID(const X509_REQ
*req
, int nid
, int lastpos
)
203 return X509at_get_attr_by_NID(req
->req_info
.attributes
, nid
, lastpos
);
206 int X509_REQ_get_attr_by_OBJ(const X509_REQ
*req
, const ASN1_OBJECT
*obj
,
209 return X509at_get_attr_by_OBJ(req
->req_info
.attributes
, obj
, lastpos
);
212 X509_ATTRIBUTE
*X509_REQ_get_attr(const X509_REQ
*req
, int loc
)
214 return X509at_get_attr(req
->req_info
.attributes
, loc
);
217 X509_ATTRIBUTE
*X509_REQ_delete_attr(X509_REQ
*req
, int loc
)
219 return X509at_delete_attr(req
->req_info
.attributes
, loc
);
222 int X509_REQ_add1_attr(X509_REQ
*req
, X509_ATTRIBUTE
*attr
)
224 if (X509at_add1_attr(&req
->req_info
.attributes
, attr
))
229 int X509_REQ_add1_attr_by_OBJ(X509_REQ
*req
,
230 const ASN1_OBJECT
*obj
, int type
,
231 const unsigned char *bytes
, int len
)
233 if (X509at_add1_attr_by_OBJ(&req
->req_info
.attributes
, obj
,
239 int X509_REQ_add1_attr_by_NID(X509_REQ
*req
,
241 const unsigned char *bytes
, int len
)
243 if (X509at_add1_attr_by_NID(&req
->req_info
.attributes
, nid
,
249 int X509_REQ_add1_attr_by_txt(X509_REQ
*req
,
250 const char *attrname
, int type
,
251 const unsigned char *bytes
, int len
)
253 if (X509at_add1_attr_by_txt(&req
->req_info
.attributes
, attrname
,
259 long X509_REQ_get_version(const X509_REQ
*req
)
261 return ASN1_INTEGER_get(req
->req_info
.version
);
264 X509_NAME
*X509_REQ_get_subject_name(const X509_REQ
*req
)
266 return req
->req_info
.subject
;
269 void X509_REQ_get0_signature(const X509_REQ
*req
, const ASN1_BIT_STRING
**psig
,
270 const X509_ALGOR
**palg
)
273 *psig
= req
->signature
;
275 *palg
= &req
->sig_alg
;
278 void X509_REQ_set0_signature(X509_REQ
*req
, ASN1_BIT_STRING
*psig
)
281 ASN1_BIT_STRING_free(req
->signature
);
282 req
->signature
= psig
;
285 int X509_REQ_set1_signature_algo(X509_REQ
*req
, X509_ALGOR
*palg
)
287 return X509_ALGOR_copy(&req
->sig_alg
, palg
);
290 int X509_REQ_get_signature_nid(const X509_REQ
*req
)
292 return OBJ_obj2nid(req
->sig_alg
.algorithm
);
295 int i2d_re_X509_REQ_tbs(X509_REQ
*req
, unsigned char **pp
)
297 req
->req_info
.enc
.modified
= 1;
298 return i2d_X509_REQ_INFO(&req
->req_info
, pp
);