summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509/x509_req.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/x509/x509_req.c')
-rw-r--r--src/lib/libcrypto/x509/x509_req.c210
1 files changed, 122 insertions, 88 deletions
diff --git a/src/lib/libcrypto/x509/x509_req.c b/src/lib/libcrypto/x509/x509_req.c
index 12725ed7e9..ae6fbd7d14 100644
--- a/src/lib/libcrypto/x509/x509_req.c
+++ b/src/lib/libcrypto/x509/x509_req.c
@@ -5,21 +5,21 @@
5 * This package is an SSL implementation written 5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com). 6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL. 7 * The implementation was written so as to conform with Netscapes SSL.
8 * 8 *
9 * This library is free for commercial and non-commercial use as long as 9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions 10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA, 11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms 13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 * 15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed. 17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution 18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used. 19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or 20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package. 21 * in documentation (online or textual) provided with the package.
22 * 22 *
23 * Redistribution and use in source and binary forms, with or without 23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions 24 * modification, are permitted provided that the following conditions
25 * are met: 25 * are met:
@@ -34,10 +34,10 @@
34 * Eric Young (eay@cryptsoft.com)" 34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library 35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-). 36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement: 38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 * 40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -49,7 +49,7 @@
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE. 51 * SUCH DAMAGE.
52 * 52 *
53 * The licence and distribution terms for any publically available version or 53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence 55 * copied and put under another distribution licence
@@ -67,86 +67,97 @@
67#include <openssl/buffer.h> 67#include <openssl/buffer.h>
68#include <openssl/pem.h> 68#include <openssl/pem.h>
69 69
70X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) 70X509_REQ *
71X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
71{ 72{
72 X509_REQ *ret; 73 X509_REQ *ret;
73 X509_REQ_INFO *ri; 74 X509_REQ_INFO *ri;
74 int i; 75 int i;
75 EVP_PKEY *pktmp; 76 EVP_PKEY *pktmp;
76 77
77 ret=X509_REQ_new(); 78 ret = X509_REQ_new();
78 if (ret == NULL) { 79 if (ret == NULL) {
79 X509err(X509_F_X509_TO_X509_REQ,ERR_R_MALLOC_FAILURE); 80 X509err(X509_F_X509_TO_X509_REQ, ERR_R_MALLOC_FAILURE);
80 goto err; 81 goto err;
81 } 82 }
82 83
83 ri=ret->req_info; 84 ri = ret->req_info;
84 85
85 ri->version->length=1; 86 ri->version->length = 1;
86 ri->version->data=(unsigned char *)malloc(1); 87 ri->version->data = (unsigned char *)malloc(1);
87 if (ri->version->data == NULL) goto err; 88 if (ri->version->data == NULL)
88 ri->version->data[0]=0; /* version == 0 */ 89 goto err;
90 ri->version->data[0] = 0; /* version == 0 */
89 91
90 if (!X509_REQ_set_subject_name(ret,X509_get_subject_name(x))) 92 if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x)))
91 goto err; 93 goto err;
92 94
93 pktmp = X509_get_pubkey(x); 95 pktmp = X509_get_pubkey(x);
94 i=X509_REQ_set_pubkey(ret,pktmp); 96 i = X509_REQ_set_pubkey(ret, pktmp);
95 EVP_PKEY_free(pktmp); 97 EVP_PKEY_free(pktmp);
96 if (!i) goto err; 98 if (!i)
99 goto err;
97 100
98 if (pkey != NULL) { 101 if (pkey != NULL) {
99 if (!X509_REQ_sign(ret,pkey,md)) 102 if (!X509_REQ_sign(ret, pkey, md))
100 goto err; 103 goto err;
101 } 104 }
102 return(ret); 105 return (ret);
106
103err: 107err:
104 X509_REQ_free(ret); 108 X509_REQ_free(ret);
105 return(NULL); 109 return (NULL);
106} 110}
107 111
108EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) 112EVP_PKEY *
113X509_REQ_get_pubkey(X509_REQ *req)
109{ 114{
110 if ((req == NULL) || (req->req_info == NULL)) 115 if ((req == NULL) || (req->req_info == NULL))
111 return(NULL); 116 return (NULL);
112 return(X509_PUBKEY_get(req->req_info->pubkey)); 117 return (X509_PUBKEY_get(req->req_info->pubkey));
113} 118}
114 119
115int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) 120int
121X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
116{ 122{
117 EVP_PKEY *xk=NULL; 123 EVP_PKEY *xk = NULL;
118 int ok=0; 124 int ok = 0;
119 125
120 xk=X509_REQ_get_pubkey(x); 126 xk = X509_REQ_get_pubkey(x);
121 switch (EVP_PKEY_cmp(xk, k)) { 127 switch (EVP_PKEY_cmp(xk, k)) {
122 case 1: 128 case 1:
123 ok=1; 129 ok = 1;
124 break; 130 break;
125 case 0: 131 case 0:
126 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH); 132 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
133 X509_R_KEY_VALUES_MISMATCH);
127 break; 134 break;
128 case -1: 135 case -1:
129 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH); 136 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
137 X509_R_KEY_TYPE_MISMATCH);
130 break; 138 break;
131 case -2: 139 case -2:
132#ifndef OPENSSL_NO_EC 140#ifndef OPENSSL_NO_EC
133 if (k->type == EVP_PKEY_EC) { 141 if (k->type == EVP_PKEY_EC) {
134 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB); 142 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
143 ERR_R_EC_LIB);
135 break; 144 break;
136 } 145 }
137#endif 146#endif
138#ifndef OPENSSL_NO_DH 147#ifndef OPENSSL_NO_DH
139 if (k->type == EVP_PKEY_DH) { 148 if (k->type == EVP_PKEY_DH) {
140 /* No idea */ 149 /* No idea */
141 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY); 150 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
151 X509_R_CANT_CHECK_DH_KEY);
142 break; 152 break;
143 } 153 }
144#endif 154#endif
145 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE); 155 X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
156 X509_R_UNKNOWN_KEY_TYPE);
146 } 157 }
147 158
148 EVP_PKEY_free(xk); 159 EVP_PKEY_free(xk);
149 return(ok); 160 return (ok);
150} 161}
151 162
152/* It seems several organisations had the same idea of including a list of 163/* It seems several organisations had the same idea of including a list of
@@ -154,31 +165,38 @@ int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
154 * used and there may be more: so the list is configurable. 165 * used and there may be more: so the list is configurable.
155 */ 166 */
156 167
157static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef}; 168static int ext_nid_list[] = {NID_ext_req, NID_ms_ext_req, NID_undef};
158 169
159static int *ext_nids = ext_nid_list; 170static int *ext_nids = ext_nid_list;
160 171
161int X509_REQ_extension_nid(int req_nid) 172int
173X509_REQ_extension_nid(int req_nid)
162{ 174{
163 int i, nid; 175 int i, nid;
164 for(i = 0; ; i++) { 176
177 for (i = 0; ; i++) {
165 nid = ext_nids[i]; 178 nid = ext_nids[i];
166 if(nid == NID_undef) return 0; 179 if (nid == NID_undef)
167 else if (req_nid == nid) return 1; 180 return 0;
181 else if (req_nid == nid)
182 return 1;
168 } 183 }
169} 184}
170 185
171int *X509_REQ_get_extension_nids(void) 186int *
187X509_REQ_get_extension_nids(void)
172{ 188{
173 return ext_nids; 189 return ext_nids;
174} 190}
175 191
176void X509_REQ_set_extension_nids(int *nids) 192void
193X509_REQ_set_extension_nids(int *nids)
177{ 194{
178 ext_nids = nids; 195 ext_nids = nids;
179} 196}
180 197
181STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) 198STACK_OF(X509_EXTENSION) *
199X509_REQ_get_extensions(X509_REQ *req)
182{ 200{
183 X509_ATTRIBUTE *attr; 201 X509_ATTRIBUTE *attr;
184 ASN1_TYPE *ext = NULL; 202 ASN1_TYPE *ext = NULL;
@@ -186,46 +204,50 @@ STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
186 const unsigned char *p; 204 const unsigned char *p;
187 205
188 if ((req == NULL) || (req->req_info == NULL) || !ext_nids) 206 if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
189 return(NULL); 207 return (NULL);
190 for (pnid = ext_nids; *pnid != NID_undef; pnid++) { 208 for (pnid = ext_nids; *pnid != NID_undef; pnid++) {
191 idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); 209 idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
192 if (idx == -1) 210 if (idx == -1)
193 continue; 211 continue;
194 attr = X509_REQ_get_attr(req, idx); 212 attr = X509_REQ_get_attr(req, idx);
195 if(attr->single) ext = attr->value.single; 213 if (attr->single)
196 else if(sk_ASN1_TYPE_num(attr->value.set)) 214 ext = attr->value.single;
215 else if (sk_ASN1_TYPE_num(attr->value.set))
197 ext = sk_ASN1_TYPE_value(attr->value.set, 0); 216 ext = sk_ASN1_TYPE_value(attr->value.set, 0);
198 break; 217 break;
199 } 218 }
200 if(!ext || (ext->type != V_ASN1_SEQUENCE)) 219 if (!ext || (ext->type != V_ASN1_SEQUENCE))
201 return NULL; 220 return NULL;
202 p = ext->value.sequence->data; 221 p = ext->value.sequence->data;
203 return (STACK_OF(X509_EXTENSION) *) 222 return (STACK_OF(X509_EXTENSION) *)ASN1_item_d2i(NULL, &p,
204 ASN1_item_d2i(NULL, &p, ext->value.sequence->length, 223 ext->value.sequence->length, ASN1_ITEM_rptr(X509_EXTENSIONS));
205 ASN1_ITEM_rptr(X509_EXTENSIONS));
206} 224}
207 225
208/* Add a STACK_OF extensions to a certificate request: allow alternative OIDs 226/* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
209 * in case we want to create a non standard one. 227 * in case we want to create a non standard one.
210 */ 228 */
211 229
212int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, 230int
213 int nid) 231X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
232 int nid)
214{ 233{
215 ASN1_TYPE *at = NULL; 234 ASN1_TYPE *at = NULL;
216 X509_ATTRIBUTE *attr = NULL; 235 X509_ATTRIBUTE *attr = NULL;
217 if(!(at = ASN1_TYPE_new()) || 236
218 !(at->value.sequence = ASN1_STRING_new())) goto err; 237 if (!(at = ASN1_TYPE_new()) ||
238 !(at->value.sequence = ASN1_STRING_new()))
239 goto err;
219 240
220 at->type = V_ASN1_SEQUENCE; 241 at->type = V_ASN1_SEQUENCE;
221 /* Generate encoding of extensions */ 242 /* Generate encoding of extensions */
222 at->value.sequence->length = 243 at->value.sequence->length = ASN1_item_i2d((ASN1_VALUE *)exts,
223 ASN1_item_i2d((ASN1_VALUE *)exts, 244 &at->value.sequence->data, ASN1_ITEM_rptr(X509_EXTENSIONS));
224 &at->value.sequence->data, 245 if (!(attr = X509_ATTRIBUTE_new()))
225 ASN1_ITEM_rptr(X509_EXTENSIONS)); 246 goto err;
226 if(!(attr = X509_ATTRIBUTE_new())) goto err; 247 if (!(attr->value.set = sk_ASN1_TYPE_new_null()))
227 if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err; 248 goto err;
228 if(!sk_ASN1_TYPE_push(attr->value.set, at)) goto err; 249 if (!sk_ASN1_TYPE_push(attr->value.set, at))
250 goto err;
229 at = NULL; 251 at = NULL;
230 attr->single = 0; 252 attr->single = 0;
231 attr->object = OBJ_nid2obj(nid); 253 attr->object = OBJ_nid2obj(nid);
@@ -233,77 +255,89 @@ int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
233 if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null())) 255 if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
234 goto err; 256 goto err;
235 } 257 }
236 if(!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) goto err; 258 if (!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr))
259 goto err;
237 return 1; 260 return 1;
238 err: 261
262err:
239 X509_ATTRIBUTE_free(attr); 263 X509_ATTRIBUTE_free(attr);
240 ASN1_TYPE_free(at); 264 ASN1_TYPE_free(at);
241 return 0; 265 return 0;
242} 266}
267
243/* This is the normal usage: use the "official" OID */ 268/* This is the normal usage: use the "official" OID */
244int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) 269int
270X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts)
245{ 271{
246 return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); 272 return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
247} 273}
248 274
249/* Request attribute functions */ 275/* Request attribute functions */
250 276
251int X509_REQ_get_attr_count(const X509_REQ *req) 277int
278X509_REQ_get_attr_count(const X509_REQ *req)
252{ 279{
253 return X509at_get_attr_count(req->req_info->attributes); 280 return X509at_get_attr_count(req->req_info->attributes);
254} 281}
255 282
256int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, 283int
257 int lastpos) 284X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos)
258{ 285{
259 return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos); 286 return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos);
260} 287}
261 288
262int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, 289int
263 int lastpos) 290X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, int lastpos)
264{ 291{
265 return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos); 292 return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos);
266} 293}
267 294
268X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) 295X509_ATTRIBUTE *
296X509_REQ_get_attr(const X509_REQ *req, int loc)
269{ 297{
270 return X509at_get_attr(req->req_info->attributes, loc); 298 return X509at_get_attr(req->req_info->attributes, loc);
271} 299}
272 300
273X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) 301X509_ATTRIBUTE *
302X509_REQ_delete_attr(X509_REQ *req, int loc)
274{ 303{
275 return X509at_delete_attr(req->req_info->attributes, loc); 304 return X509at_delete_attr(req->req_info->attributes, loc);
276} 305}
277 306
278int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) 307int
308X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr)
279{ 309{
280 if(X509at_add1_attr(&req->req_info->attributes, attr)) return 1; 310 if (X509at_add1_attr(&req->req_info->attributes, attr))
311 return 1;
281 return 0; 312 return 0;
282} 313}
283 314
284int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, 315int
285 const ASN1_OBJECT *obj, int type, 316X509_REQ_add1_attr_by_OBJ(X509_REQ *req, const ASN1_OBJECT *obj, int type,
286 const unsigned char *bytes, int len) 317 const unsigned char *bytes, int len)
287{ 318{
288 if(X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj, 319 if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj,
289 type, bytes, len)) return 1; 320 type, bytes, len))
321 return 1;
290 return 0; 322 return 0;
291} 323}
292 324
293int X509_REQ_add1_attr_by_NID(X509_REQ *req, 325int
294 int nid, int type, 326X509_REQ_add1_attr_by_NID(X509_REQ *req, int nid, int type,
295 const unsigned char *bytes, int len) 327 const unsigned char *bytes, int len)
296{ 328{
297 if(X509at_add1_attr_by_NID(&req->req_info->attributes, nid, 329 if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid,
298 type, bytes, len)) return 1; 330 type, bytes, len))
331 return 1;
299 return 0; 332 return 0;
300} 333}
301 334
302int X509_REQ_add1_attr_by_txt(X509_REQ *req, 335int
303 const char *attrname, int type, 336X509_REQ_add1_attr_by_txt(X509_REQ *req, const char *attrname, int type,
304 const unsigned char *bytes, int len) 337 const unsigned char *bytes, int len)
305{ 338{
306 if(X509at_add1_attr_by_txt(&req->req_info->attributes, attrname, 339 if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname,
307 type, bytes, len)) return 1; 340 type, bytes, len))
341 return 1;
308 return 0; 342 return 0;
309} 343}