• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 #include <string.h>
13 #include <tee_log.h>
14 #include <rsa/rsa_local.h>
15 #include <openssl/ossl_typ.h>
16 #include <openssl/x509.h>
17 #include <openssl/rsa.h>
18 #include <securec.h>
19 #include "crypto_wrapper.h"
20 #include "crypto_inner_interface.h"
21 
22 static uint8_t g_rsa_key_oid[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
23 static uint8_t g_ecc_key_oid[] = { 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x2, 0x1 };
24 
x509_crl_validate(uint8_t * cert,uint32_t cert_len,uint8_t * parent_key,uint32_t parent_key_len)25 int x509_crl_validate(uint8_t *cert, uint32_t cert_len, uint8_t *parent_key, uint32_t parent_key_len)
26 {
27     X509_CRL *cert_x509 = NULL;
28     EVP_PKEY *pkey      = NULL;
29     int ret             = -1;
30 
31     if (cert == NULL || parent_key == NULL)
32         return -1;
33 
34     cert_x509 = d2i_X509_CRL(NULL, (const uint8_t **)(&cert), (long)cert_len);
35     if (cert_x509 == NULL) {
36         tloge("d2i cert failed");
37         goto error;
38     }
39 
40     pkey = d2i_PUBKEY(&pkey, (const unsigned char **)(&parent_key), parent_key_len);
41     if (pkey == NULL) {
42         tloge("d2i pubkey failed");
43         goto error;
44     }
45 
46     ret = X509_CRL_verify(cert_x509, pkey);
47 error:
48     X509_CRL_free(cert_x509);
49     EVP_PKEY_free(pkey);
50 
51     return ret;
52 }
x509_cert_validate(uint8_t * cert,uint32_t cert_len,uint8_t * parent_key,uint32_t parent_key_len)53 int x509_cert_validate(uint8_t *cert, uint32_t cert_len, uint8_t *parent_key, uint32_t parent_key_len)
54 {
55     X509 *cert_x509 = NULL;
56     EVP_PKEY *pkey  = NULL;
57     int ret         = -1;
58 
59     if (cert == NULL || parent_key == NULL)
60         return -1;
61 
62     cert_x509 = d2i_X509(NULL, (const unsigned char **)(&cert), (long)cert_len);
63     if (cert_x509 == NULL) {
64         tloge("d2i cert failed");
65         goto error;
66     }
67 
68     pkey = d2i_PUBKEY(&pkey, (const unsigned char **)(&parent_key), (long)parent_key_len);
69     if (pkey == NULL) {
70         tloge("d2i pubkey failed");
71         goto error;
72     }
73 
74     ret = X509_verify(cert_x509, pkey);
75 
76 error:
77     X509_free(cert_x509);
78     EVP_PKEY_free(pkey);
79 
80     return ret;
81 }
82 
get_keytype_from_sp(const uint8_t * in,uint32_t inlen)83 int get_keytype_from_sp(const uint8_t *in, uint32_t inlen)
84 {
85     int tag = 0;
86     int class;
87     long tmplen        = (long)inlen;
88     const uint8_t *end = in + inlen;
89 
90     if (in == NULL)
91         return -1;
92 
93     (void)ASN1_get_object(&in, &tmplen, &tag, &class, end - in);
94     if (tag != V_ASN1_SEQUENCE) {
95         tloge("tag1 invalid type");
96         return -1;
97     }
98 
99     tag = 0;
100     end = in + tmplen;
101     (void)ASN1_get_object(&in, &tmplen, &tag, &class, end - in);
102     if (tag != V_ASN1_SEQUENCE) {
103         tloge("tag2 invalid type");
104         return -1;
105     }
106 
107     tag = 0;
108     end = in + tmplen;
109     (void)ASN1_get_object(&in, &tmplen, &tag, &class, end - in);
110     if (tag != V_ASN1_OBJECT) {
111         tloge("tag1 invalid type");
112         return -1;
113     }
114 
115     if ((tmplen == (long)sizeof(g_rsa_key_oid)) && (memcmp(in, g_rsa_key_oid, tmplen) == 0))
116         return RSA_ALG;
117     if ((tmplen == (long)sizeof(g_ecc_key_oid)) && (memcmp(in, g_ecc_key_oid, tmplen) == 0))
118         return ECC_ALG;
119 
120     /* It is not RSA nor ECC key */
121     return -1;
122 }
123 
ecc_nid_boringssl2tom(uint32_t nid)124 static int ecc_nid_boringssl2tom(uint32_t nid)
125 {
126     uint32_t index                 = 0;
127     crypto_u2u nid_tom_to_boring[] = {
128         { NID_X9_62_prime192v1, NIST_P192 }, { NID_secp224r1, NIST_P224 }, { NID_X9_62_prime256v1, NIST_P256 },
129         { NID_secp384r1, NIST_P384 },        { NID_secp521r1, NIST_P521 },
130     };
131     for (; index < sizeof(nid_tom_to_boring) / sizeof(crypto_u2u); index++) {
132         if (nid == nid_tom_to_boring[index].src)
133             return nid_tom_to_boring[index].dest;
134     }
135     tloge("invalid nid 0x%x\n", nid);
136     return -1;
137 }
138 
get_rsa_pub_from_cert(rsa_pub_key_t * rsa_pub,const uint8_t * in,uint32_t inlen)139 static int get_rsa_pub_from_cert(rsa_pub_key_t *rsa_pub, const uint8_t *in, uint32_t inlen)
140 {
141     RSA *rsa = NULL;
142     uint32_t n_len, e_len;
143     rsa     = d2i_RSA_PUBKEY(NULL, &in, inlen);
144     if (rsa == NULL) {
145         tloge("d2i rsa pubkey failed");
146         return -1;
147     }
148 
149     bool check = (rsa->e == NULL || rsa->n == NULL);
150     if (check) {
151         tloge("n or e is NULL");
152         RSA_free(rsa);
153         return -1;
154     }
155 
156     n_len = (uint32_t)BN_num_bytes(rsa->n);
157     e_len = (uint32_t)BN_num_bytes(rsa->e);
158     if (n_len > sizeof(rsa_pub->n) || e_len > sizeof(rsa_pub->e)) {
159         tloge("pub key buffer too small");
160         RSA_free(rsa);
161         return -1;
162     }
163 
164     rsa_pub->n_len = (uint32_t)BN_bn2bin(rsa->n, rsa_pub->n);
165     rsa_pub->e_len = (uint32_t)BN_bn2bin(rsa->e, rsa_pub->e);
166 
167     RSA_free(rsa);
168     return 0;
169 }
170 
get_ecc_pub_from_cert_helper(ecc_pub_key_t * ecc_pub,const EC_GROUP * group,const EC_POINT * point)171 static int get_ecc_pub_from_cert_helper(ecc_pub_key_t *ecc_pub, const EC_GROUP *group, const EC_POINT *point)
172 {
173     BIGNUM *x = NULL;
174     BIGNUM *y = NULL;
175     BN_CTX *ctx = NULL;
176     int ret = -1;
177 
178     x = BN_new();
179     y = BN_new();
180     ctx = BN_CTX_new();
181     if (x == NULL || y == NULL || ctx == NULL) {
182         tloge("all bn ctx failed");
183         goto clean;
184     }
185 
186     if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx) != 1) {
187         tloge("all bn ctx failed");
188         goto clean;
189     }
190 
191     if ((uint32_t)BN_num_bytes(x) <= sizeof(ecc_pub->x) && (uint32_t)BN_num_bytes(y) <= sizeof(ecc_pub->y)) {
192         ecc_pub->x_len = (uint32_t)BN_bn2bin(x, ecc_pub->x);
193         ecc_pub->y_len = (uint32_t)BN_bn2bin(y, ecc_pub->y);
194         ret = 0;
195     } else {
196         tloge("ec pub buffer too small");
197     }
198 
199 clean:
200     BN_free(x);
201     BN_free(y);
202     BN_CTX_free(ctx);
203 
204     return ret;
205 }
206 
get_ecc_pub_from_cert(ecc_pub_key_t * ecc_pub,const uint8_t * in,uint32_t inlen)207 static int get_ecc_pub_from_cert(ecc_pub_key_t *ecc_pub, const uint8_t *in, uint32_t inlen)
208 {
209     EC_KEY *ec_key        = NULL;
210     const EC_GROUP *group = NULL;
211     const EC_POINT *point = NULL;
212     int ret               = -1;
213 
214     ec_key = d2i_EC_PUBKEY(NULL, &in, inlen);
215     if (ec_key == NULL) {
216         tloge("d2i ec pub failed");
217         return -1;
218     }
219 
220     group = EC_KEY_get0_group(ec_key);
221     if (group == NULL) {
222         tloge("get ec group failed");
223         goto clean;
224     }
225 
226     ret = ecc_nid_boringssl2tom(EC_GROUP_get_curve_name(group));
227     if (ret < 0) {
228         tloge("get ec group failed");
229         goto clean;
230     }
231     ecc_pub->domain = (uint32_t)ret;
232 
233     point = EC_KEY_get0_public_key(ec_key);
234     if (point == NULL) {
235         tloge("get ec group failed");
236         goto clean;
237     }
238 
239     ret = get_ecc_pub_from_cert_helper(ecc_pub, group, point);
240 clean:
241     EC_KEY_free(ec_key);
242 
243     return ret;
244 }
245 
import_pub_from_sp(void * pub,const uint8_t * in,uint32_t inlen)246 int import_pub_from_sp(void *pub, const uint8_t *in, uint32_t inlen)
247 {
248     int32_t ret;
249     uint32_t keytype;
250 
251     if (pub == NULL || in == NULL) {
252         tloge("invalid args");
253         return -1;
254     }
255 
256     ret = get_keytype_from_sp(in, inlen);
257     if (ret < 0) {
258         tloge("get key type failed");
259         return -1;
260     }
261 
262     keytype = (uint32_t)ret;
263     switch (keytype) {
264     case RSA_ALG:
265         return get_rsa_pub_from_cert(pub, in, inlen);
266     case ECC_ALG:
267         return get_ecc_pub_from_cert(pub, in, inlen);
268     default: /* Keytype not supported */
269         tloge("invalid key type");
270         return -1;
271     }
272 }
273 
public_get_subject_public_key(uint8_t * pub,uint32_t pub_size,bool check_size,const uint8_t * cert,uint32_t cert_len)274 static int public_get_subject_public_key(uint8_t *pub, uint32_t pub_size,
275     bool check_size, const uint8_t *cert, uint32_t cert_len)
276 {
277     X509 *cert_x509 = NULL;
278     int len         = -1;
279     EVP_PKEY *pkey  = NULL;
280 
281     if (pub == NULL || cert == NULL)
282         return -1;
283 
284     cert_x509 = d2i_X509(NULL, (const unsigned char **)(&cert), cert_len);
285     if (cert_x509 == NULL) {
286         tloge("d2i x509 cert failed");
287         goto clean;
288     }
289 
290     pkey = X509_get_pubkey(cert_x509);
291     if (pkey == NULL) {
292         tloge("x509 get pubkey failed");
293         goto clean;
294     }
295 
296     if (check_size) {
297         int pub_len;
298 
299         pub_len = i2d_PUBKEY(pkey, NULL);
300         if ((uint32_t)pub_len > pub_size) {
301             tloge("invalid pub size, %d", pub_len);
302             goto clean;
303         }
304     }
305 
306     len = i2d_PUBKEY(pkey, &pub);
307 
308 clean:
309     EVP_PKEY_free(pkey);
310     X509_free(cert_x509);
311 
312     return len;
313 }
314 
get_subject_public_key_new(uint8_t * pub,uint32_t pub_size,const uint8_t * cert,uint32_t cert_len)315 int get_subject_public_key_new(uint8_t *pub, uint32_t pub_size, const uint8_t *cert, uint32_t cert_len)
316 {
317     return public_get_subject_public_key(pub, pub_size, true, cert, cert_len);
318 }
319 
320 /* this is not safe, but it's an export API */
get_subject_public_key(uint8_t * pub,const uint8_t * cert,uint32_t cert_len)321 int get_subject_public_key(uint8_t *pub, const uint8_t *cert, uint32_t cert_len)
322 {
323     return public_get_subject_public_key(pub, 0, false, cert, cert_len);
324 }
325 
get_validity_from_cert(validity_period_t * vd,uint8_t * cert,uint32_t cert_len)326 int get_validity_from_cert(validity_period_t *vd, uint8_t *cert, uint32_t cert_len)
327 {
328     X509 *cert_x509   = NULL;
329     ASN1_STRING *time = NULL;
330     int ret           = -1;
331 
332     if (vd == NULL || cert == NULL) {
333         tloge("invalid args");
334         return -1;
335     }
336 
337     cert_x509 = d2i_X509(NULL, (const unsigned char **)(&cert), cert_len);
338     if (cert_x509 == NULL) {
339         tloge("d2i x509 cert failed");
340         goto clean;
341     }
342 
343     time = X509_get_notBefore(cert_x509);
344     if (memcpy_s(vd->start, sizeof(vd->start), ASN1_STRING_data(time), ASN1_STRING_length(time))) {
345         tloge("copy start time failed");
346         goto clean;
347     }
348 
349     time = X509_get_notAfter(cert_x509);
350     if (memcpy_s(vd->end, sizeof(vd->end), ASN1_STRING_data(time), ASN1_STRING_length(time))) {
351         tloge("copy end time failed");
352         goto clean;
353     }
354 
355     ret = 0;
356 
357 clean:
358     X509_free(cert_x509);
359 
360     return ret;
361 }
362 
get_subject_by_name(uint8_t * buff,uint32_t len,const char * name,const uint8_t * cert,uint32_t cert_len)363 static int get_subject_by_name(uint8_t *buff, uint32_t len, const char *name, const uint8_t *cert, uint32_t cert_len)
364 {
365     X509 *cert_x509       = NULL;
366     X509_NAME *x_name     = NULL;
367     ASN1_OBJECT *asn1_obj = NULL;
368     int ret               = -1;
369 
370     if (buff == NULL || cert == NULL)
371         return -1;
372 
373     cert_x509 = d2i_X509(NULL, (const unsigned char **)(&cert), cert_len);
374     if (cert_x509 == NULL) {
375         tloge("d2i x509 cert failed");
376         goto clean;
377     }
378 
379     x_name = X509_get_subject_name(cert_x509);
380     if (x_name == NULL) {
381         tloge("x509 get subject name failed");
382         goto clean;
383     }
384 
385     asn1_obj = OBJ_txt2obj(name, 0);
386     if (asn1_obj == NULL) {
387         tloge("c2i asn1 obj failed");
388         goto clean;
389     }
390 
391     ret = X509_NAME_get_text_by_OBJ(x_name, asn1_obj, (char *)buff, (int)len);
392     if (ret < 0) {
393         tloge("x509 get text by obj failed");
394         goto clean;
395     }
396 
397 clean:
398     ASN1_OBJECT_free(asn1_obj);
399     X509_free(cert_x509);
400 
401     return ret;
402 }
403 
get_subject_x509_cn(uint8_t * name,uint32_t name_size,const uint8_t * cert,uint32_t cert_len)404 int get_subject_x509_cn(uint8_t *name, uint32_t name_size, const uint8_t *cert, uint32_t cert_len)
405 {
406     return get_subject_by_name(name, name_size, "CN", cert, cert_len);
407 }
408 
get_subject_CN(uint8_t * name,uint32_t name_size,const uint8_t * cert,uint32_t cert_len)409 int get_subject_CN(uint8_t *name, uint32_t name_size, const uint8_t *cert, uint32_t cert_len)
410 {
411     return get_subject_x509_cn(name, name_size, cert, cert_len);
412 }
413 
get_subject_x509_ou(uint8_t * name,uint32_t name_size,const uint8_t * cert,uint32_t cert_len)414 int get_subject_x509_ou(uint8_t *name, uint32_t name_size, const uint8_t *cert, uint32_t cert_len)
415 {
416     return get_subject_by_name(name, name_size, "OU", cert, cert_len);
417 }
418 
get_subject_OU(uint8_t * name,uint32_t name_size,const uint8_t * cert,uint32_t cert_len)419 int get_subject_OU(uint8_t *name, uint32_t name_size, const uint8_t *cert, uint32_t cert_len)
420 {
421     return get_subject_x509_ou(name, name_size, cert, cert_len);
422 }
423 
get_serial_number_from_cert(uint8_t * serial_number,uint32_t serial_number_size,uint8_t * cert,uint32_t cert_len)424 int get_serial_number_from_cert(uint8_t *serial_number, uint32_t serial_number_size, uint8_t *cert, uint32_t cert_len)
425 {
426     X509 *cert_x509           = NULL;
427     ASN1_INTEGER *asn1_serial = NULL;
428     int serial_len;
429     int ret = -1;
430 
431     if (serial_number == NULL || cert == NULL)
432         return -1;
433 
434     cert_x509 = d2i_X509(NULL, (const unsigned char **)(&cert), (long)cert_len);
435     if (cert_x509 == NULL) {
436         tloge("d2i x509 cert failed");
437         goto clean;
438     }
439 
440     asn1_serial = X509_get_serialNumber(cert_x509);
441     if (asn1_serial == NULL) {
442         tloge("get serial num failed");
443         goto clean;
444     }
445 
446     serial_len = i2d_ASN1_INTEGER(asn1_serial, NULL);
447     if ((uint32_t)serial_len > serial_number_size) {
448         tloge("serial buffer too small, %u/%d", serial_number_size, serial_len);
449         goto clean;
450     }
451 
452     ret = i2d_ASN1_INTEGER(asn1_serial, &serial_number);
453 
454 clean:
455     X509_free(cert_x509);
456 
457     return ret;
458 }
459 
get_issuer_from_cert(uint8_t * issuer,uint32_t issuer_size,uint8_t * crl,uint32_t crl_len)460 int get_issuer_from_cert(uint8_t *issuer, uint32_t issuer_size, uint8_t *crl, uint32_t crl_len)
461 {
462     X509 *crl_x509    = NULL;
463     X509_NAME *x_name = NULL;
464     int ret           = -1;
465     int issuer_len;
466 
467     if (issuer == NULL || crl == NULL)
468         return -1;
469 
470     crl_x509 = d2i_X509(NULL, (const unsigned char **)(&crl), (long)crl_len);
471     if (crl_x509 == NULL) {
472         tloge("d2i x509 cert failed");
473         goto clean;
474     }
475 
476     x_name = X509_get_issuer_name(crl_x509);
477     if (x_name == NULL) {
478         tloge("get issuer failed");
479         goto clean;
480     }
481 
482     issuer_len = i2d_X509_NAME(x_name, NULL);
483     if ((uint32_t)issuer_len > issuer_size) {
484         tloge("crl len too small, %d/%u", issuer_len, issuer_size);
485         goto clean;
486     }
487 
488     ret = i2d_X509_NAME(x_name, &issuer);
489 clean:
490     X509_free(crl_x509);
491 
492     return ret;
493 }
494