• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <openssl/asn1.h>
11 #include <openssl/asn1t.h>
12 #include <openssl/bn.h>
13 #include <openssl/err.h>
14 #include <openssl/evp.h>
15 #include <openssl/mem.h>
16 #include <openssl/obj.h>
17 #include <openssl/pem.h>
18 #include <openssl/x509.h>
19 
20 #include "../asn1/internal.h"
21 #include "internal.h"
22 
23 
X509_REQ_get_version(const X509_REQ * req)24 long X509_REQ_get_version(const X509_REQ *req) {
25   return ASN1_INTEGER_get(req->req_info->version);
26 }
27 
X509_REQ_get_subject_name(const X509_REQ * req)28 X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req) {
29   return req->req_info->subject;
30 }
31 
X509_REQ_get_pubkey(const X509_REQ * req)32 EVP_PKEY *X509_REQ_get_pubkey(const X509_REQ *req) {
33   if (req == NULL) {
34     return NULL;
35   }
36   return X509_PUBKEY_get(req->req_info->pubkey);
37 }
38 
X509_REQ_get0_pubkey(const X509_REQ * req)39 EVP_PKEY *X509_REQ_get0_pubkey(const X509_REQ *req) {
40   if (req == NULL) {
41     return NULL;
42   }
43   return X509_PUBKEY_get0(req->req_info->pubkey);
44 }
45 
X509_REQ_check_private_key(const X509_REQ * x,const EVP_PKEY * k)46 int X509_REQ_check_private_key(const X509_REQ *x, const EVP_PKEY *k) {
47   const EVP_PKEY *xk = X509_REQ_get0_pubkey(x);
48   if (xk == NULL) {
49     return 0;
50   }
51 
52   int ret = EVP_PKEY_cmp(xk, k);
53   if (ret > 0) {
54     return 1;
55   }
56 
57   switch (ret) {
58     case 0:
59       OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
60       return 0;
61     case -1:
62       OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
63       return 0;
64     case -2:
65       if (EVP_PKEY_id(k) == EVP_PKEY_EC) {
66         OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB);
67       } else {
68         OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
69       }
70       return 0;
71   }
72 
73   return 0;
74 }
75 
X509_REQ_extension_nid(int req_nid)76 int X509_REQ_extension_nid(int req_nid) {
77   return req_nid == NID_ext_req || req_nid == NID_ms_ext_req;
78 }
79 
STACK_OF(X509_EXTENSION)80 STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(const X509_REQ *req) {
81   if (req == NULL || req->req_info == NULL) {
82     return NULL;
83   }
84 
85   int idx = X509_REQ_get_attr_by_NID(req, NID_ext_req, -1);
86   if (idx == -1) {
87     idx = X509_REQ_get_attr_by_NID(req, NID_ms_ext_req, -1);
88   }
89   if (idx == -1) {
90     return NULL;
91   }
92 
93   const X509_ATTRIBUTE *attr = X509_REQ_get_attr(req, idx);
94   // TODO(davidben): |X509_ATTRIBUTE_get0_type| is not const-correct. It should
95   // take and return a const pointer.
96   const ASN1_TYPE *ext = X509_ATTRIBUTE_get0_type((X509_ATTRIBUTE *)attr, 0);
97   if (!ext || ext->type != V_ASN1_SEQUENCE) {
98     return NULL;
99   }
100   const unsigned char *p = ext->value.sequence->data;
101   return (STACK_OF(X509_EXTENSION) *)ASN1_item_d2i(
102       NULL, &p, ext->value.sequence->length, ASN1_ITEM_rptr(X509_EXTENSIONS));
103 }
104 
105 // Add a STACK_OF extensions to a certificate request: allow alternative OIDs
106 // in case we want to create a non standard one.
107 
X509_REQ_add_extensions_nid(X509_REQ * req,const STACK_OF (X509_EXTENSION)* exts,int nid)108 int X509_REQ_add_extensions_nid(X509_REQ *req,
109                                 const STACK_OF(X509_EXTENSION) *exts, int nid) {
110   // Generate encoding of extensions
111   unsigned char *ext = NULL;
112   int ext_len =
113       ASN1_item_i2d((ASN1_VALUE *)exts, &ext, ASN1_ITEM_rptr(X509_EXTENSIONS));
114   if (ext_len <= 0) {
115     return 0;
116   }
117   int ret = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, ext_len);
118   OPENSSL_free(ext);
119   return ret;
120 }
121 
122 // This is the normal usage: use the "official" OID
X509_REQ_add_extensions(X509_REQ * req,const STACK_OF (X509_EXTENSION)* exts)123 int X509_REQ_add_extensions(X509_REQ *req,
124                             const STACK_OF(X509_EXTENSION) *exts) {
125   return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
126 }
127 
X509_REQ_get_attr_count(const X509_REQ * req)128 int X509_REQ_get_attr_count(const X509_REQ *req) {
129   return (int)sk_X509_ATTRIBUTE_num(req->req_info->attributes);
130 }
131 
X509_REQ_get_attr_by_NID(const X509_REQ * req,int nid,int lastpos)132 int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) {
133   const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
134   if (obj == NULL) {
135     return -1;
136   }
137   return X509_REQ_get_attr_by_OBJ(req, obj, lastpos);
138 }
139 
X509_REQ_get_attr_by_OBJ(const X509_REQ * req,const ASN1_OBJECT * obj,int lastpos)140 int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj,
141                              int lastpos) {
142   if (req->req_info->attributes == NULL) {
143     return -1;
144   }
145   lastpos++;
146   if (lastpos < 0) {
147     lastpos = 0;
148   }
149   int n = (int)sk_X509_ATTRIBUTE_num(req->req_info->attributes);
150   for (; lastpos < n; lastpos++) {
151     const X509_ATTRIBUTE *attr =
152         sk_X509_ATTRIBUTE_value(req->req_info->attributes, lastpos);
153     if (OBJ_cmp(attr->object, obj) == 0) {
154       return lastpos;
155     }
156   }
157   return -1;
158 }
159 
X509_REQ_get_attr(const X509_REQ * req,int loc)160 X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) {
161   if (req->req_info->attributes == NULL || loc < 0 ||
162       sk_X509_ATTRIBUTE_num(req->req_info->attributes) <= (size_t)loc) {
163     return NULL;
164   }
165   return sk_X509_ATTRIBUTE_value(req->req_info->attributes, loc);
166 }
167 
X509_REQ_delete_attr(X509_REQ * req,int loc)168 X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) {
169   if (req->req_info->attributes == NULL || loc < 0 ||
170       sk_X509_ATTRIBUTE_num(req->req_info->attributes) <= (size_t)loc) {
171     return NULL;
172   }
173   return sk_X509_ATTRIBUTE_delete(req->req_info->attributes, loc);
174 }
175 
X509_REQ_add0_attr(X509_REQ * req,X509_ATTRIBUTE * attr)176 static int X509_REQ_add0_attr(X509_REQ *req, X509_ATTRIBUTE *attr) {
177   if (req->req_info->attributes == NULL) {
178     req->req_info->attributes = sk_X509_ATTRIBUTE_new_null();
179   }
180   if (req->req_info->attributes == NULL ||
181       !sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) {
182     return 0;
183   }
184 
185   return 1;
186 }
187 
X509_REQ_add1_attr(X509_REQ * req,const X509_ATTRIBUTE * attr)188 int X509_REQ_add1_attr(X509_REQ *req, const X509_ATTRIBUTE *attr) {
189   X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_dup(attr);
190   if (new_attr == NULL || !X509_REQ_add0_attr(req, new_attr)) {
191     X509_ATTRIBUTE_free(new_attr);
192     return 0;
193   }
194 
195   return 1;
196 }
197 
X509_REQ_add1_attr_by_OBJ(X509_REQ * req,const ASN1_OBJECT * obj,int attrtype,const unsigned char * data,int len)198 int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, const ASN1_OBJECT *obj,
199                               int attrtype, const unsigned char *data,
200                               int len) {
201   X509_ATTRIBUTE *attr =
202       X509_ATTRIBUTE_create_by_OBJ(NULL, obj, attrtype, data, len);
203   if (attr == NULL || !X509_REQ_add0_attr(req, attr)) {
204     X509_ATTRIBUTE_free(attr);
205     return 0;
206   }
207 
208   return 1;
209 }
210 
X509_REQ_add1_attr_by_NID(X509_REQ * req,int nid,int attrtype,const unsigned char * data,int len)211 int X509_REQ_add1_attr_by_NID(X509_REQ *req, int nid, int attrtype,
212                               const unsigned char *data, int len) {
213   X509_ATTRIBUTE *attr =
214       X509_ATTRIBUTE_create_by_NID(NULL, nid, attrtype, data, len);
215   if (attr == NULL || !X509_REQ_add0_attr(req, attr)) {
216     X509_ATTRIBUTE_free(attr);
217     return 0;
218   }
219 
220   return 1;
221 }
222 
X509_REQ_add1_attr_by_txt(X509_REQ * req,const char * attrname,int attrtype,const unsigned char * data,int len)223 int X509_REQ_add1_attr_by_txt(X509_REQ *req, const char *attrname, int attrtype,
224                               const unsigned char *data, int len) {
225   X509_ATTRIBUTE *attr =
226       X509_ATTRIBUTE_create_by_txt(NULL, attrname, attrtype, data, len);
227   if (attr == NULL || !X509_REQ_add0_attr(req, attr)) {
228     X509_ATTRIBUTE_free(attr);
229     return 0;
230   }
231 
232   return 1;
233 }
234 
X509_REQ_get0_signature(const X509_REQ * req,const ASN1_BIT_STRING ** psig,const X509_ALGOR ** palg)235 void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig,
236                              const X509_ALGOR **palg) {
237   if (psig != NULL) {
238     *psig = req->signature;
239   }
240   if (palg != NULL) {
241     *palg = req->sig_alg;
242   }
243 }
244 
X509_REQ_get_signature_nid(const X509_REQ * req)245 int X509_REQ_get_signature_nid(const X509_REQ *req) {
246   return OBJ_obj2nid(req->sig_alg->algorithm);
247 }
248 
i2d_re_X509_REQ_tbs(X509_REQ * req,unsigned char ** pp)249 int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) {
250   asn1_encoding_clear(&req->req_info->enc);
251   return i2d_X509_REQ_INFO(req->req_info, pp);
252 }
253