1/*
2 * Copyright (c) 2007-2016, Cameron Rich
3 *
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 * * Neither the name of the axTLS project nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/**
32 * Some primitive asn methods for extraction ASN.1 data.
33 */
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <time.h>
39#include "os_port.h"
40#include "crypto.h"
41#include "crypto_misc.h"
42
43/* 1.2.840.113549.1.1 OID prefix - handle the following */
44/* md5WithRSAEncryption(4) */
45/* sha1WithRSAEncryption(5) */
46/* sha256WithRSAEncryption (11) */
47/* sha384WithRSAEncryption (12) */
48/* sha512WithRSAEncryption (13) */
49static const uint8_t sig_oid_prefix[] =
50{
51 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01
52};
53
54/* 1.3.14.3.2.29 SHA1 with RSA signature */
55static const uint8_t sig_sha1WithRSAEncrypt[] =
56{
57 0x2b, 0x0e, 0x03, 0x02, 0x1d
58};
59
60/* 2.16.840.1.101.3.4.2.1 SHA-256 */
61static const uint8_t sig_sha256[] =
62{
63 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01
64};
65
66/* 2.16.840.1.101.3.4.2.2 SHA-384 */
67static const uint8_t sig_sha384[] =
68{
69 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02
70};
71
72/* 2.16.840.1.101.3.4.2.3 SHA-512 */
73static const uint8_t sig_sha512[] =
74{
75 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03
76};
77
78static const uint8_t sig_subject_alt_name[] =
79{
80 0x55, 0x1d, 0x11
81};
82
83static const uint8_t sig_basic_constraints[] =
84{
85 0x55, 0x1d, 0x13
86};
87
88static const uint8_t sig_key_usage[] =
89{
90 0x55, 0x1d, 0x0f
91};
92
93/* CN, O, OU, L, C, ST */
94static const uint8_t g_dn_types[] = { 3, 10, 11, 7, 6, 8 };
95
96uint32_t get_asn1_length(const uint8_t *buf, int *offset)
97{
98 int i;
99 uint32_t len;
100
101 if (!(buf[*offset] & 0x80)) /* short form */
102 {
103 len = buf[(*offset)++];
104 }
105 else /* long form */
106 {
107 int length_bytes = buf[(*offset)++]&0x7f;
108 if (length_bytes > 4) /* limit number of bytes */
109 return 0;
110
111 len = 0;
112 for (i = 0; i < length_bytes; i++)
113 {
114 len <<= 8;
115 len += buf[(*offset)++];
116 }
117 }
118
119 return len;
120}
121
122/**
123 * Skip the ASN1.1 object type and its length. Get ready to read the object's
124 * data.
125 */
126int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type)
127{
128 if (buf[*offset] != obj_type)
129 return X509_NOT_OK;
130
131 (*offset)++;
132 return get_asn1_length(buf, offset);
133}
134
135/**
136 * Skip over an ASN.1 object type completely. Get ready to read the next
137 * object.
138 */
139int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type)
140{
141 int len;
142
143 if (buf[*offset] != obj_type)
144 return X509_NOT_OK;
145 (*offset)++;
146 len = get_asn1_length(buf, offset);
147 *offset += len;
148 return 0;
149}
150
151/**
152 * Read an integer value for ASN.1 data
153 * Note: This function allocates memory which must be freed by the user.
154 */
155int asn1_get_big_int(const uint8_t *buf, int *offset, uint8_t **object)
156{
157 int len;
158
159 if ((len = asn1_next_obj(buf, offset, ASN1_INTEGER)) < 0)
160 goto end_big_int;
161
162 if (len > 1 && buf[*offset] == 0x00) /* ignore the negative byte */
163 {
164 len--;
165 (*offset)++;
166 }
167
168 *object = (uint8_t *)malloc(len);
169 memcpy(*object, &buf[*offset], len);
170 *offset += len;
171
172end_big_int:
173 return len;
174}
175
176/**
177 * Read an integer value for ASN.1 data
178 */
179int asn1_get_int(const uint8_t *buf, int *offset, int32_t *val)
180{
181 int res = X509_OK;
182 int len;
183 int i;
184
185 if ((len = asn1_next_obj(buf, offset, ASN1_INTEGER)) < 0 ||
186 len > sizeof(int32_t))
187 {
188 res = X509_NOT_OK;
189 goto end_int;
190 }
191
192 *val = 0;
193 for (i = 0; i < len; i++)
194 {
195 *val <<= 8;
196 *val |= buf[(*offset)++];
197 }
198
199end_int:
200 return res;
201}
202
203/**
204 * Read an boolean value for ASN.1 data
205 */
206int asn1_get_bool(const uint8_t *buf, int *offset, bool *val)
207{
208 int res = X509_OK;
209
210 if (asn1_next_obj(buf, offset, ASN1_BOOLEAN) != 1)
211 {
212 res = X509_NOT_OK;
213 goto end_bool;
214 }
215
216 /* DER demands that "If the encoding represents the boolean value TRUE,
217 its single contents octet shall have all eight bits set to one."
218 Thus only 0 and 255 are valid encoded values. */
219 *val = buf[(*offset)++] == 0xFF;
220
221end_bool:
222 return res;
223}
224
225/**
226 * Convert an ASN.1 bit string into a 32 bit integer. Used for key usage
227 */
228int asn1_get_bit_string_as_int(const uint8_t *buf, int *offset, uint32_t *val)
229{
230 int res = X509_OK;
231 int len, i;
232
233 if ((len = asn1_next_obj(buf, offset, ASN1_BIT_STRING)) < 0 || len > 5)
234 {
235 res = X509_NOT_OK;
236 goto end_bit_string_as_int;
237 }
238
239 /* number of bits left unused in the final byte of content */
240 (*offset)++;
241 len--;
242 *val = 0;
243
244 /* not sure why key usage doesn't used proper DER spec version */
245 for (i = len-1; i >= 0; --i)
246 {
247 *val <<= 8;
248 *val |= buf[(*offset) + i];
249 }
250
251 *offset += len;
252
253end_bit_string_as_int:
254 return res;
255}
256
257/**
258 * Get all the RSA private key specifics from an ASN.1 encoded file
259 */
260int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx)
261{
262 int offset = 7;
263 uint8_t *modulus = NULL, *priv_exp = NULL, *pub_exp = NULL;
264 int mod_len, priv_len, pub_len;
265#ifdef CONFIG_BIGINT_CRT
266 uint8_t *p = NULL, *q = NULL, *dP = NULL, *dQ = NULL, *qInv = NULL;
267 int p_len, q_len, dP_len, dQ_len, qInv_len;
268#endif
269
270 /* not in der format */
271 if (buf[0] != ASN1_SEQUENCE) /* basic sanity check */
272 {
273#ifdef CONFIG_SSL_FULL_MODE
274 printf("Error: This is not a valid ASN.1 file\n");
275#endif
276 return X509_INVALID_PRIV_KEY;
277 }
278
279 /* Use the private key to mix up the RNG if possible. */
280 RNG_custom_init(buf, len);
281
282 mod_len = asn1_get_big_int(buf, &offset, &modulus);
283 pub_len = asn1_get_big_int(buf, &offset, &pub_exp);
284 priv_len = asn1_get_big_int(buf, &offset, &priv_exp);
285
286 if (mod_len <= 0 || pub_len <= 0 || priv_len <= 0)
287 return X509_INVALID_PRIV_KEY;
288
289#ifdef CONFIG_BIGINT_CRT
290 p_len = asn1_get_big_int(buf, &offset, &p);
291 q_len = asn1_get_big_int(buf, &offset, &q);
292 dP_len = asn1_get_big_int(buf, &offset, &dP);
293 dQ_len = asn1_get_big_int(buf, &offset, &dQ);
294 qInv_len = asn1_get_big_int(buf, &offset, &qInv);
295
296 if (p_len <= 0 || q_len <= 0 || dP_len <= 0 || dQ_len <= 0 || qInv_len <= 0)
297 return X509_INVALID_PRIV_KEY;
298
299 RSA_priv_key_new(rsa_ctx,
300 modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len,
301 p, p_len, q, p_len, dP, dP_len, dQ, dQ_len, qInv, qInv_len);
302
303 free(p);
304 free(q);
305 free(dP);
306 free(dQ);
307 free(qInv);
308#else
309 RSA_priv_key_new(rsa_ctx,
310 modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len);
311#endif
312
313 free(modulus);
314 free(priv_exp);
315 free(pub_exp);
316 return X509_OK;
317}
318
319/**
320 * Get the time of a certificate. Ignore hours/minutes/seconds.
321 */
322static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t)
323{
324 int ret = X509_NOT_OK, len, t_offset, abs_year;
325 struct tm tm;
326
327 /* see http://tools.ietf.org/html/rfc5280#section-4.1.2.5 */
328 if (buf[*offset] == ASN1_UTC_TIME)
329 {
330 (*offset)++;
331
332 len = get_asn1_length(buf, offset);
333 t_offset = *offset;
334
335 memset(&tm, 0, sizeof(struct tm));
336 tm.tm_year = (buf[t_offset] - '0')*10 + (buf[t_offset+1] - '0');
337
338 if (tm.tm_year < 50) /* 1951-2050 thing */
339 {
340 tm.tm_year += 100;
341 }
342
343 tm.tm_mon = (buf[t_offset+2] - '0')*10 + (buf[t_offset+3] - '0') - 1;
344 tm.tm_mday = (buf[t_offset+4] - '0')*10 + (buf[t_offset+5] - '0');
345 tm.tm_hour = (buf[t_offset+6] - '0')*10 + (buf[t_offset+7] - '0');
346 tm.tm_min = (buf[t_offset+8] - '0')*10 + (buf[t_offset+9] - '0');
347 tm.tm_sec = (buf[t_offset+10] - '0')*10 + (buf[t_offset+11] - '0');
348 *t = mktime(&tm);
349 *offset += len;
350 ret = X509_OK;
351 }
352 else if (buf[*offset] == ASN1_GENERALIZED_TIME)
353 {
354 (*offset)++;
355
356 len = get_asn1_length(buf, offset);
357 t_offset = *offset;
358
359 memset(&tm, 0, sizeof(struct tm));
360 abs_year = ((buf[t_offset] - '0')*1000 +
361 (buf[t_offset+1] - '0')*100 + (buf[t_offset+2] - '0')*10 +
362 (buf[t_offset+3] - '0'));
363
364 if (abs_year <= 1901)
365 {
366 tm.tm_year = 1;
367 tm.tm_mon = 0;
368 tm.tm_mday = 1;
369 }
370 else
371 {
372 tm.tm_year = abs_year - 1900;
373 tm.tm_mon = (buf[t_offset+4] - '0')*10 +
374 (buf[t_offset+5] - '0') - 1;
375 tm.tm_mday = (buf[t_offset+6] - '0')*10 + (buf[t_offset+7] - '0');
376 tm.tm_hour = (buf[t_offset+8] - '0')*10 + (buf[t_offset+9] - '0');
377 tm.tm_min = (buf[t_offset+10] - '0')*10 + (buf[t_offset+11] - '0');
378 tm.tm_sec = (buf[t_offset+12] - '0')*10 + (buf[t_offset+13] - '0');
379 *t = mktime(&tm);
380 }
381
382 *offset += len;
383 ret = X509_OK;
384 }
385
386 return ret;
387}
388
389/**
390 * Get the version type of a certificate
391 */
392int asn1_version(const uint8_t *cert, int *offset, int *val)
393{
394 (*offset) += 2; /* get past explicit tag */
395 return asn1_get_int(cert, offset, val);
396}
397
398/**
399 * Retrieve the notbefore and notafter certificate times.
400 */
401int asn1_validity(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
402{
403 return (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
404 asn1_get_utc_time(cert, offset, &x509_ctx->not_before) ||
405 asn1_get_utc_time(cert, offset, &x509_ctx->not_after));
406}
407
408/**
409 * Get the components of a distinguished name
410 */
411static int asn1_get_oid_x520(const uint8_t *buf, int *offset)
412{
413 int dn_type = 0;
414 int len;
415
416 if ((len = asn1_next_obj(buf, offset, ASN1_OID)) < 0)
417 goto end_oid;
418
419 /* expect a sequence of 2.5.4.[x] where x is a one of distinguished name
420 components we are interested in. */
421 if (len == 3 && buf[(*offset)++] == 0x55 && buf[(*offset)++] == 0x04)
422 dn_type = buf[(*offset)++];
423 else
424 {
425 *offset += len; /* skip over it */
426 }
427
428end_oid:
429 return dn_type;
430}
431
432/**
433 * Obtain an ASN.1 printable string type.
434 */
435static int asn1_get_printable_str(const uint8_t *buf, int *offset, char **str)
436{
437 int len = X509_NOT_OK;
438 int asn1_type = buf[*offset];
439
440 /* some certs have this awful crud in them for some reason */
441 if (asn1_type != ASN1_PRINTABLE_STR &&
442 asn1_type != ASN1_PRINTABLE_STR2 &&
443 asn1_type != ASN1_TELETEX_STR &&
444 asn1_type != ASN1_IA5_STR &&
445 asn1_type != ASN1_UNICODE_STR)
446 goto end_pnt_str;
447
448 (*offset)++;
449 len = get_asn1_length(buf, offset);
450
451 if (asn1_type == ASN1_UNICODE_STR)
452 {
453 int i;
454 *str = (char *)malloc(len/2+1); /* allow for null */
455
456 for (i = 0; i < len; i += 2)
457 (*str)[i/2] = buf[*offset + i + 1];
458
459 (*str)[len/2] = 0; /* null terminate */
460 }
461 else
462 {
463 *str = (char *)malloc(len+1); /* allow for null */
464 memcpy(*str, &buf[*offset], len);
465 (*str)[len] = 0; /* null terminate */
466 }
467
468 *offset += len;
469
470end_pnt_str:
471 return len;
472}
473
474/**
475 * Get the subject name (or the issuer) of a certificate.
476 */
477int asn1_name(const uint8_t *cert, int *offset, char *dn[])
478{
479 int ret = X509_NOT_OK;
480 int dn_type;
481 char *tmp;
482
483 if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0)
484 goto end_name;
485
486 while (asn1_next_obj(cert, offset, ASN1_SET) >= 0)
487 {
488 int i, found = 0;
489
490 if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
491 (dn_type = asn1_get_oid_x520(cert, offset)) < 0)
492 goto end_name;
493
494 tmp = NULL;
495
496 if (asn1_get_printable_str(cert, offset, &tmp) < 0)
497 {
498 free(tmp);
499 goto end_name;
500 }
501
502 /* find the distinguished named type */
503 for (i = 0; i < X509_NUM_DN_TYPES; i++)
504 {
505 if (dn_type == g_dn_types[i])
506 {
507 if (dn[i] == NULL)
508 {
509 dn[i] = tmp;
510 found = 1;
511 break;
512 }
513 }
514 }
515
516 if (found == 0) /* not found so get rid of it */
517 {
518 free(tmp);
519 }
520 }
521
522 ret = X509_OK;
523end_name:
524 return ret;
525}
526
527/**
528 * Read the modulus and public exponent of a certificate.
529 */
530int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
531{
532 int ret = X509_NOT_OK, mod_len, pub_len;
533 uint8_t *modulus = NULL, *pub_exp = NULL;
534
535 if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
536 asn1_skip_obj(cert, offset, ASN1_SEQUENCE) ||
537 asn1_next_obj(cert, offset, ASN1_BIT_STRING) < 0)
538 goto end_pub_key;
539
540 (*offset)++; /* ignore the padding bit field */
541
542 if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0)
543 goto end_pub_key;
544
545 mod_len = asn1_get_big_int(cert, offset, &modulus);
546 pub_len = asn1_get_big_int(cert, offset, &pub_exp);
547
548 RSA_pub_key_new(&x509_ctx->rsa_ctx, modulus, mod_len, pub_exp, pub_len);
549
550 free(modulus);
551 free(pub_exp);
552 ret = X509_OK;
553
554end_pub_key:
555 return ret;
556}
557
558#ifdef CONFIG_SSL_CERT_VERIFICATION
559/**
560 * Read the signature of the certificate.
561 */
562int asn1_signature(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
563{
564 int ret = X509_NOT_OK;
565
566 if (cert[(*offset)++] != ASN1_BIT_STRING)
567 goto end_sig;
568
569 x509_ctx->sig_len = get_asn1_length(cert, offset)-1;
570 (*offset)++; /* ignore bit string padding bits */
571 x509_ctx->signature = (uint8_t *)malloc(x509_ctx->sig_len);
572 memcpy(x509_ctx->signature, &cert[*offset], x509_ctx->sig_len);
573 *offset += x509_ctx->sig_len;
574 ret = X509_OK;
575
576end_sig:
577 return ret;
578}
579
580/*
581 * Compare 2 distinguished name components for equality
582 * @return 0 if a match
583 */
584static int asn1_compare_dn_comp(const char *dn1, const char *dn2)
585{
586 int ret;
587
588 if (dn1 == NULL && dn2 == NULL)
589 ret = 0;
590 else
591 ret = (dn1 && dn2) ? strcmp(dn1, dn2) : 1;
592
593 return ret;
594}
595
596/**
597 * Clean up all of the CA certificates.
598 */
599void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx)
600{
601 int i = 0;
602
603 if (ca_cert_ctx == NULL)
604 return;
605
606 while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
607 {
608 x509_free(ca_cert_ctx->cert[i]);
609 ca_cert_ctx->cert[i++] = NULL;
610 }
611
612 free(ca_cert_ctx);
613}
614
615/*
616 * Compare 2 distinguished names for equality
617 * @return 0 if a match
618 */
619int asn1_compare_dn(char * const dn1[], char * const dn2[])
620{
621 int i;
622
623 for (i = 0; i < X509_NUM_DN_TYPES; i++)
624 {
625 if (asn1_compare_dn_comp(dn1[i], dn2[i]))
626 return 1;
627 }
628
629 return 0; /* all good */
630}
631
632int asn1_find_oid(const uint8_t* cert, int* offset,
633 const uint8_t* oid, int oid_length)
634{
635 int seqlen;
636 if ((seqlen = asn1_next_obj(cert, offset, ASN1_SEQUENCE))> 0)
637 {
638 int end = *offset + seqlen;
639
640 while (*offset < end)
641 {
642 int type = cert[(*offset)++];
643 int length = get_asn1_length(cert, offset);
644 int noffset = *offset + length;
645
646 if (type == ASN1_SEQUENCE)
647 {
648 type = cert[(*offset)++];
649 length = get_asn1_length(cert, offset);
650
651 if (type == ASN1_OID && length == oid_length &&
652 memcmp(cert + *offset, oid, oid_length) == 0)
653 {
654 *offset += oid_length;
655 return 1;
656 }
657 }
658
659 *offset = noffset;
660 }
661 }
662
663 return 0;
664}
665
666int asn1_is_subject_alt_name(const uint8_t *cert, int offset)
667{
668 if (asn1_find_oid(cert, &offset, sig_subject_alt_name,
669 sizeof(sig_subject_alt_name)))
670 {
671 return offset;
672 }
673
674 return 0;
675}
676
677int asn1_is_basic_constraints(const uint8_t *cert, int offset)
678{
679 if (asn1_find_oid(cert, &offset, sig_basic_constraints,
680 sizeof(sig_basic_constraints)))
681 {
682 return offset;
683 }
684
685 return 0;
686}
687
688int asn1_is_key_usage(const uint8_t *cert, int offset)
689{
690 if (asn1_find_oid(cert, &offset, sig_key_usage,
691 sizeof(sig_key_usage)))
692 {
693 return offset;
694 }
695
696 return 0;
697}
698
699bool asn1_is_critical_ext(const uint8_t *buf, int *offset)
700{
701 /* critical is optional */
702 bool res = false;
703
704 if (asn1_next_obj(buf, offset, ASN1_BOOLEAN) == 1)
705 res = buf[(*offset)++] == 0xFF;
706
707 return res;
708}
709
710#endif /* CONFIG_SSL_CERT_VERIFICATION */
711
712/**
713 * Read the signature type of the certificate. We only support RSA-MD5 and
714 * RSA-SHA1 signature types.
715 */
716int asn1_signature_type(const uint8_t *cert,
717 int *offset, X509_CTX *x509_ctx)
718{
719 int ret = X509_NOT_OK, len;
720
721 if (cert[(*offset)++] != ASN1_OID)
722 goto end_check_sig;
723
724 len = get_asn1_length(cert, offset);
725
726 if (len == sizeof(sig_sha1WithRSAEncrypt) &&
727 memcmp(sig_sha1WithRSAEncrypt, &cert[*offset],
728 sizeof(sig_sha1WithRSAEncrypt)) == 0)
729 {
730 x509_ctx->sig_type = SIG_TYPE_SHA1;
731 }
732 else if (len == sizeof(sig_sha256) &&
733 memcmp(sig_sha256, &cert[*offset],
734 sizeof(sig_sha256)) == 0)
735 {
736 x509_ctx->sig_type = SIG_TYPE_SHA256;
737 }
738 else if (len == sizeof(sig_sha384) &&
739 memcmp(sig_sha384, &cert[*offset],
740 sizeof(sig_sha384)) == 0)
741 {
742 x509_ctx->sig_type = SIG_TYPE_SHA384;
743 }
744 else if (len == sizeof(sig_sha512) &&
745 memcmp(sig_sha512, &cert[*offset],
746 sizeof(sig_sha512)) == 0)
747 {
748 x509_ctx->sig_type = SIG_TYPE_SHA512;
749 }
750 else
751 {
752 if (memcmp(sig_oid_prefix, &cert[*offset], sizeof(sig_oid_prefix)))
753 {
754#ifdef CONFIG_SSL_FULL_MODE
755 int i;
756 printf("invalid digest: ");
757
758 for (i = 0; i < len; i++)
759 printf("%02x ", cert[*offset + i]);
760
761 printf("\n");
762#endif
763 goto end_check_sig; /* unrecognised cert type */
764 }
765
766 x509_ctx->sig_type = cert[*offset + sizeof(sig_oid_prefix)];
767 }
768
769 *offset += len;
770 asn1_skip_obj(cert, offset, ASN1_NULL); /* if it's there */
771 ret = X509_OK;
772
773end_check_sig:
774 return ret;
775}
776
777