File Coverage

inc/matrixssl-3-9-3-open/crypto/keyformat/asn1.c
Criterion Covered Total %
statement 157 299 52.5
branch 60 124 48.3
condition n/a
subroutine n/a
pod n/a
total 217 423 51.3


line stmt bran cond sub pod time code
1             /**
2             * @file asn1.c
3             * @version 950bba4 (HEAD -> master)
4             *
5             * DER/BER coding.
6             */
7             /*
8             * Copyright (c) 2013-2017 INSIDE Secure Corporation
9             * Copyright (c) PeerSec Networks, 2002-2011
10             * All Rights Reserved
11             *
12             * The latest version of this code is available at http://www.matrixssl.org
13             *
14             * This software is open source; you can redistribute it and/or modify
15             * it under the terms of the GNU General Public License as published by
16             * the Free Software Foundation; either version 2 of the License, or
17             * (at your option) any later version.
18             *
19             * This General Public License does NOT permit incorporating this software
20             * into proprietary programs. If you are unable to comply with the GPL, a
21             * commercial license for this software may be purchased from INSIDE at
22             * http://www.insidesecure.com/
23             *
24             * This program is distributed in WITHOUT ANY WARRANTY; without even the
25             * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26             * See the GNU General Public License for more details.
27             *
28             * You should have received a copy of the GNU General Public License
29             * along with this program; if not, write to the Free Software
30             * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31             * http://www.gnu.org/copyleft/gpl.html
32             */
33             /******************************************************************************/
34              
35             #include "../cryptoImpl.h"
36              
37             /* Compute tag length when it is known that p points to valid ASN.1 DER
38             encoding, no larger than 16 megabytes. */
39 0           uint32_t getAsnTagLenUnsafe(const unsigned char *p)
40             {
41             uint32_t len;
42              
43             /* Return 0 for uninitialized data or NULL. */
44 0 0         if (p == NULL || *p == 0)
    0          
45             {
46 0           return 0;
47             }
48 0           len = p[1];
49 0 0         if (len >= 0x80)
50             {
51 0           unsigned char lenbytes[3] = { 0, 0, 0 }; /* Size up-to 16 Mbytes. */
52 0           len -= 0x80; /* Compute number of bytes in encoding. */
53 0 0         if (len == 0 || len >= 4)
    0          
54             {
55             /* Although the function is "Unsafe", check for too long
56             length encoding, because in future some parser may accept
57             input > 4 gigabytes. */
58 0           return 0; /* Too large length. */
59             }
60             /* Note: */
61 0           memcpy(lenbytes + 3 - len, p + 2, len);
62 0           len =
63 0           len + 2 +
64 0           ((lenbytes[0] << 16) |
65 0           (lenbytes[1] << 8) |
66 0           (lenbytes[2] << 0));
67             }
68             else
69             {
70 0           len += 2; /* Tag and length byte. */
71             }
72 0           return len;
73             }
74              
75             /******************************************************************************/
76             /*
77             On success, p will be updated to point to first character of value and
78             len will contain number of bytes in value.
79              
80             Indefinite length formats return ASN_UNKNOWN_LEN and *len will simply
81             be updated with the overall remaining length
82             */
83 106883           int32_t getAsnLength(const unsigned char **pp, psSize_t size, psSize_t *len)
84             {
85 106883           uint32_t len32 = 0;
86             int32_t rc;
87              
88 106883 50         if ((rc = getAsnLength32(pp, size, &len32, 0)) < 0)
89             {
90 0           return rc;
91             }
92 106883           *len = (uint16_t) (len32 & 0xFFFF);
93 106883           return PS_SUCCESS;
94             }
95              
96 217749           int32_t getAsnLength32(const unsigned char **pp, uint32_t size, uint32_t *len,
97             uint32_t indefinite)
98             {
99             const unsigned char *c, *end;
100             uint32_t l;
101              
102 217749           c = *pp;
103 217749           end = c + size;
104 217749           *len = 0;
105 217749 50         if (end - c < 1)
106             {
107             psTraceCrypto("getAsnLength called on empty buffer\n");
108 0           return PS_LIMIT_FAIL;
109             }
110             /*
111             If the high bit is set, the lower 7 bits represent the number of
112             bytes that follow defining length
113             If the high bit is not set, the lower 7 represent the actual length
114             */
115 217749           l = *c & 0x7F;
116 217749 100         if (*c & 0x80)
117             {
118             /* Point c at first length byte */
119 23608           c++;
120             /* Ensure we have that many bytes left in the buffer. */
121 23608 50         if (end - c < l)
122             {
123             psTraceCrypto("Malformed stream in getAsnLength\n");
124 0           return PS_LIMIT_FAIL;
125             }
126              
127 23608           switch (l)
128             {
129             case 4:
130 0           l = *c << 24; c++;
131 0           l |= *c << 16; c++;
132 0           l |= *c << 8; c++;
133 0           l |= *c; c++;
134 0           break;
135             case 3:
136 0           l = *c << 16; c++;
137 0           l |= *c << 8; c++;
138 0           l |= *c; c++;
139 0           break;
140             case 2:
141 21238           l = *c << 8; c++;
142 21238           l |= *c; c++;
143 21238           break;
144             case 1:
145 2370           l = *c; c++;
146 2370           break;
147             /*
148             If the length byte has high bit only set, it's an indefinite
149             length. If allowed, return the number of bytes remaining in buffer.
150             */
151             case 0:
152 0 0         if (indefinite)
153             {
154 0           *pp = c;
155 0           *len = size - 1;
156 0           return ASN_UNKNOWN_LEN;
157             }
158 0           return PS_LIMIT_FAIL;
159              
160             /* Make sure there aren't more than 4 bytes of length specifier. */
161             default:
162             psTraceCrypto("Malformed stream in getAsnLength\n");
163 23608           return PS_LIMIT_FAIL;
164             }
165             }
166             else
167             {
168 194141           c++;
169             }
170              
171             /* Stream parsers will not require the entire data to be present */
172 217749 50         if (!indefinite && (end - c < l))
    50          
173             {
174             psTraceCrypto("getAsnLength longer than remaining buffer.\n");
175 0           return PS_LIMIT_FAIL;
176             }
177              
178 217749           *pp = c;
179 217749           *len = l;
180 217749           return PS_SUCCESS;
181             }
182              
183             /******************************************************************************/
184             /*
185             Callback to extract a sequence length from the DER stream
186             Verifies that 'len' bytes are >= 'seqlen'
187             Move pp to the first character in the sequence
188             */
189             /* #define DISABLE_STRICT_ASN_LENGTH_CHECK */
190 73426           int32_t getAsnSequence32(const unsigned char **pp, uint32_t size,
191             uint32_t *len, uint32_t indefinite)
192             {
193 73426           const unsigned char *p = *pp;
194             int32_t rc;
195              
196 73426           rc = PS_PARSE_FAIL;
197 73426 50         if (size < 1 || *(p++) != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
    100          
    50          
198 73415           ((rc = getAsnLength32(&p, size - 1, len, indefinite)) < 0))
199             {
200             psTraceCrypto("ASN getSequence failed\n");
201 11           return rc;
202             }
203             #ifndef DISABLE_STRICT_ASN_LENGTH_CHECK
204             /* The (p - *pp) is taking the length encoding bytes into account */
205 73415 50         if (!indefinite && (size - ((uint32_t) (p - *pp))) < *len)
    50          
206             {
207             /* It isn't cool but some encodings have an outer length layer that
208             is smaller than the inner. Normally you'll want this check but if
209             you're hitting this case, you could try skipping it to see if there
210             is an error in the encoding */
211             psTraceCrypto("ASN_SEQUENCE parse found length greater than total\n");
212             psTraceCrypto("Could try enabling DISABLE_STRICT_ASN_LENGTH_CHECK\n");
213 0           return PS_LIMIT_FAIL;
214             }
215             #endif
216 73415           *pp = p;
217 73426           return rc;
218             }
219              
220 59444           int32_t getAsnSequence(const unsigned char **pp, psSize_t size, psSize_t *len)
221             {
222 59444           uint32_t len32 = 0;
223             int32_t rc;
224              
225 59444 100         if ((rc = getAsnSequence32(pp, size, &len32, 0)) < 0)
226             {
227 8           return rc;
228             }
229 59436           *len = (uint16_t) (len32 & 0xFFFF);
230 59444           return PS_SUCCESS;
231             }
232              
233             /******************************************************************************/
234             /*
235             Extract a set length from the DER stream. Will also test that there
236             is enough data available to hold it all. Returns LIMIT_FAIL if not.
237             */
238 22835           int32_t getAsnSet32(const unsigned char **pp, uint32_t size, uint32_t *len,
239             uint32_t indefinite)
240             {
241 22835           const unsigned char *p = *pp;
242             int32_t rc;
243              
244 22835           rc = PS_PARSE_FAIL;
245 22835 50         if (size < 1 || *(p++) != (ASN_SET | ASN_CONSTRUCTED) ||
    50          
    50          
246 22835           ((rc = getAsnLength32(&p, size - 1, len, indefinite)) < 0))
247             {
248             psTraceCrypto("ASN getSet failed\n");
249 0           return rc;
250             }
251             /* Account for overhead needed to get the length */
252 22835 50         if (size < ((uint32_t) (p - *pp) + *len))
253             {
254 0           return PS_LIMIT_FAIL;
255             }
256 22835           *pp = p;
257 22835           return rc;
258             }
259              
260 22835           int32_t getAsnSet(const unsigned char **pp, psSize_t size, psSize_t *len)
261             {
262 22835           uint32_t len32 = 0;
263             int32_t rc;
264              
265 22835 50         if ((rc = getAsnSet32(pp, size, &len32, 0)) < 0)
266             {
267 0           return rc;
268             }
269 22835           *len = (uint16_t) (len32 & 0xFFFF);
270 22835           return PS_SUCCESS;
271             }
272             /******************************************************************************/
273             /*
274             Get an enumerated value
275             */
276 0           int32_t getAsnEnumerated(const unsigned char **pp, uint32_t len, int32_t *val)
277             {
278 0           const unsigned char *p = *pp, *end;
279             uint32_t ui, slen;
280             int32_t rc;
281             uint32_t vlen;
282              
283 0           rc = PS_PARSE_FAIL;
284 0           end = p + len;
285 0 0         if (len < 1 || *(p++) != ASN_ENUMERATED ||
    0          
    0          
286 0           ((rc = getAsnLength32(&p, len - 1, &vlen, 0)) < 0))
287             {
288             psTraceCrypto("ASN getInteger failed from the start\n");
289 0           return rc;
290             }
291             /*
292             This check prevents us from having a big positive integer where the
293             high bit is set because it will be encoded as 5 bytes (with leading
294             blank byte). If that is required, a getUnsigned routine should be used
295             */
296 0 0         if (vlen > sizeof(int32_t) || (uint32_t) (end - p) < vlen)
    0          
297             {
298             psTraceCrypto("ASN getInteger had limit failure\n");
299 0           return PS_LIMIT_FAIL;
300             }
301 0           ui = 0;
302             /*
303             If high bit is set, it's a negative integer, so perform the two's compliment
304             Otherwise do a standard big endian read (most likely case for RSA)
305             */
306 0 0         if (*p & 0x80)
307             {
308 0 0         while (vlen > 0)
309             {
310 0           ui = (ui << 8) | (*p ^ 0xFF);
311 0           p++;
312 0           vlen--;
313             }
314 0           slen = ui;
315 0           slen++;
316 0           slen = -slen;
317 0           *val = slen;
318             }
319             else
320             {
321 0 0         while (vlen > 0)
322             {
323 0           ui = (ui << 8) | *p;
324 0           p++;
325 0           vlen--;
326             }
327 0           *val = ui;
328             }
329 0           *pp = p;
330 0           return PS_SUCCESS;
331             }
332              
333             /******************************************************************************/
334             /*
335             Get an integer
336             */
337 3516           int32_t getAsnInteger(const unsigned char **pp, uint32_t len, int32_t *val)
338             {
339 3516           const unsigned char *p = *pp, *end;
340             uint32_t ui, slen;
341             int32_t rc;
342             uint32_t vlen;
343              
344 3516           rc = PS_PARSE_FAIL;
345 3516           end = p + len;
346 3516 50         if (len < 1 || *(p++) != ASN_INTEGER ||
    50          
    50          
347 3516           ((rc = getAsnLength32(&p, len - 1, &vlen, 0)) < 0))
348             {
349             psTraceCrypto("ASN getInteger failed from the start\n");
350 0           return rc;
351             }
352             /*
353             This check prevents us from having a big positive integer where the
354             high bit is set because it will be encoded as 5 bytes (with leading
355             blank byte). If that is required, a getUnsigned routine should be used
356             */
357 3516 50         if (vlen > sizeof(int32_t) || (uint32_t) (end - p) < vlen)
    50          
358             {
359             psTraceCrypto("ASN getInteger had limit failure\n");
360 0           return PS_LIMIT_FAIL;
361             }
362 3516           ui = 0;
363             /*
364             If high bit is set, it's a negative integer, so perform the two's compliment
365             Otherwise do a standard big endian read (most likely case for RSA)
366             */
367 3516 50         if (*p & 0x80)
368             {
369 0 0         while (vlen > 0)
370             {
371 0           ui = (ui << 8) | (*p ^ 0xFF);
372 0           p++;
373 0           vlen--;
374             }
375 0           slen = ui;
376 0           slen++;
377 0           slen = -slen;
378 0           *val = slen;
379             }
380             else
381             {
382 7066 100         while (vlen > 0)
383             {
384 3550           ui = (ui << 8) | *p;
385 3550           p++;
386 3550           vlen--;
387             }
388 3516           *val = ui;
389             }
390 3516           *pp = p;
391 3516           return PS_SUCCESS;
392             }
393              
394             /******************************************************************************/
395             /*
396             Implementation specific OID parser
397             */
398 11102           int32_t getAsnAlgorithmIdentifier(const unsigned char **pp, uint32_t len,
399             int32_t *oi, psSize_t *paramLen)
400             {
401 11102           const unsigned char *p = *pp, *end;
402             int32_t rc;
403             uint32_t llen;
404              
405 11102           rc = PS_PARSE_FAIL;
406 11102           end = p + len;
407 11102 50         if (len < 1 || (rc = getAsnSequence32(&p, len, &llen, 0)) < 0)
    100          
408             {
409             psTraceCrypto("getAsnAlgorithmIdentifier failed on inital parse\n");
410 2           return rc;
411             }
412             /* Always checks for parameter length */
413 11100 50         if (end - p < 1)
414             {
415 0           return PS_LIMIT_FAIL;
416             }
417 11100           rc = getAsnOID(&p, llen, oi, 1, paramLen);
418 11100           *pp = p;
419 11102           return rc;
420             }
421              
422             /******************************************************************************/
423             /**
424             Parse ASN.1 DER encoded OBJECT bytes into an OID array.
425             @param[in] der Pointer to start of OBJECT encoding.
426             @param[in] derlen Number of bytes pointed to by 'der'.
427             @param[out] oid Caller allocated array to receive OID, of
428             at least MAX_OID_LEN elements.
429             @return Number of OID elements written to 'oid', 0 on error.
430             */
431 10831           uint8_t asnParseOid(const unsigned char *der, psSize_t derlen,
432             uint32_t oid[MAX_OID_LEN])
433             {
434             const unsigned char *end;
435             uint8_t n, sanity;
436              
437 10831 50         if (derlen < 1)
438             {
439 0           return 0;
440             }
441 10831           end = der + derlen;
442             /* First two OID elements are single octet, base 40 for some reason */
443 10831           oid[0] = *der / 40;
444 10831           oid[1] = *der % 40;
445 10831           der++;
446             /* Zero the remainder of OID and leave n == 2 */
447 151634 100         for (n = MAX_OID_LEN - 1; n > 2; n--)
448             {
449 140803           oid[n] = 0;
450             }
451 38355 100         while (der < end && n < MAX_OID_LEN)
    50          
452             {
453             /* If the high bit is 0, it's short form variable length quantity */
454 27524 100         if (!(*der & 0x80))
455             {
456 24558           oid[n++] = *der++;
457             }
458             else
459             {
460 2966           sanity = 0;
461             /* Long form. High bit means another (lower) 7 bits following */
462             do
463             {
464 7371           oid[n] |= (*der & 0x7F);
465             /* A clear high bit ends the byte sequence */
466 7371 100         if (!(*der & 0x80))
467             {
468 2966           break;
469             }
470             /* Allow a maximum of 4 x 7 bit shifts (28 bits) */
471 4405 50         if (++sanity > 4)
472             {
473 0           return 0;
474             }
475             /* Make room for the next 7 bits */
476 4405           oid[n] <<= 7;
477 4405           der++;
478             }
479 4405 50         while (der < end);
480 2966           der++;
481 2966           n++;
482             }
483             }
484 10831 50         if (n < MAX_OID_LEN)
485             {
486 10831           return n;
487             }
488 0           return 0;
489             }
490              
491             #ifndef MATRIXSSL_NO_OID_DATABASE
492              
493             /* This function uses computed OID sums as base and adds suitable number of
494             multiples of OID_COLLISION in case the first known oid with the number
495             did not match. If function fails the value will be >= 32768. */
496 11100           static void checkAsnOidDatabase(int32_t *oi,
497             const unsigned char *oidStart,
498             uint32_t oidLen)
499             {
500             /* The values are represented as C strings, although they contain
501             binary data. Therefore the type needs to be const char *. */
502             const char *oid_hex;
503              
504             /* Loop until match is found, adding multiples of OID_COLLISION in case of
505             mismatch. */
506             while (1)
507             {
508 16648           switch (*oi)
509             {
510 10           case OID_SHA1_ALG: oid_hex = OID_SHA1_ALG_HEX; break;
511 0           case OID_SHA224_ALG: oid_hex = OID_SHA224_ALG_HEX; break;
512 2207           case OID_SHA256_ALG: oid_hex = OID_SHA256_ALG_HEX; break;
513 0           case OID_SHA384_ALG: oid_hex = OID_SHA384_ALG_HEX; break;
514 0           case OID_SHA512_ALG: oid_hex = OID_SHA512_ALG_HEX; break;
515 0           case OID_MD2_ALG: oid_hex = OID_MD2_ALG_HEX; break;
516 600           case OID_MD5_ALG: oid_hex = OID_MD5_ALG_HEX; break;
517 0           case OID_MD2_RSA_SIG: oid_hex = OID_MD2_RSA_SIG_HEX; break;
518 0           case OID_MD5_RSA_SIG: oid_hex = OID_MD5_RSA_SIG_HEX; break;
519 600           case OID_SHA1_RSA_SIG: oid_hex = OID_SHA1_RSA_SIG_HEX; break;
520 0           case OID_SHA1_RSA_SIG2: oid_hex = OID_SHA1_RSA_SIG2_HEX; break;
521 0           case OID_ID_MGF1: oid_hex = OID_ID_MGF1_HEX; break;
522 0           case OID_RSASSA_PSS: oid_hex = OID_RSASSA_PSS_HEX; break;
523 0           case OID_SHA224_RSA_SIG: oid_hex = OID_SHA224_RSA_SIG_HEX; break;
524 4858           case OID_SHA256_RSA_SIG: oid_hex = OID_SHA256_RSA_SIG_HEX; break;
525 60           case OID_SHA384_RSA_SIG: oid_hex = OID_SHA384_RSA_SIG_HEX; break;
526 30           case OID_SHA512_RSA_SIG: oid_hex = OID_SHA512_RSA_SIG_HEX; break;
527 0           case OID_SHA1_DSA_SIG: oid_hex = OID_SHA1_DSA_SIG_HEX; break;
528 0           case OID_SHA1_ECDSA_SIG: oid_hex = OID_SHA1_ECDSA_SIG_HEX; break;
529 0           case OID_SHA224_ECDSA_SIG: oid_hex = OID_SHA224_ECDSA_SIG_HEX; break;
530 50           case OID_SHA256_ECDSA_SIG: oid_hex = OID_SHA256_ECDSA_SIG_HEX; break;
531 160           case OID_SHA384_ECDSA_SIG: oid_hex = OID_SHA384_ECDSA_SIG_HEX; break;
532 0           case OID_SHA512_ECDSA_SIG: oid_hex = OID_SHA512_ECDSA_SIG_HEX; break;
533 2912           case OID_RSA_KEY_ALG: oid_hex = OID_RSA_KEY_ALG_HEX; break;
534 0           case OID_DSA_KEY_ALG: oid_hex = OID_DSA_KEY_ALG_HEX; break;
535 105           case OID_ECDSA_KEY_ALG: oid_hex = OID_ECDSA_KEY_ALG_HEX; break;
536 0           case OID_DES_EDE3_CBC: oid_hex = OID_DES_EDE3_CBC_HEX; break;
537 0           case OID_AES_128_CBC: oid_hex = OID_AES_128_CBC_HEX; break;
538 0           case OID_AES_128_WRAP: oid_hex = OID_AES_128_WRAP_HEX; break;
539 0           case OID_AES_128_GCM: oid_hex = OID_AES_128_GCM_HEX; break;
540 0           case OID_AES_192_CBC: oid_hex = OID_AES_192_CBC_HEX; break;
541 0           case OID_AES_192_WRAP: oid_hex = OID_AES_192_WRAP_HEX; break;
542 0           case OID_AES_192_GCM: oid_hex = OID_AES_192_GCM_HEX; break;
543 0           case OID_AES_256_CBC: oid_hex = OID_AES_256_CBC_HEX; break;
544 0           case OID_AES_256_WRAP: oid_hex = OID_AES_256_WRAP_HEX; break;
545 0           case OID_AES_256_GCM: oid_hex = OID_AES_256_GCM_HEX; break;
546 0           case OID_AES_CMAC: oid_hex = OID_AES_CMAC_HEX; break;
547 0           case OID_AES_CBC_CMAC_128: oid_hex = OID_AES_CBC_CMAC_128_HEX; break;
548 0           case OID_AES_CBC_CMAC_192: oid_hex = OID_AES_CBC_CMAC_192_HEX; break;
549 0           case OID_AES_CBC_CMAC_256: oid_hex = OID_AES_CBC_CMAC_256_HEX; break;
550 0           case OID_AUTH_ENC_256_SUM: oid_hex = OID_AUTH_ENC_256_SUM_HEX; break;
551 0           case OID_PKCS_PBKDF2: oid_hex = OID_PKCS_PBKDF2_HEX; break;
552 0           case OID_PKCS_PBES2: oid_hex = OID_PKCS_PBES2_HEX; break;
553 30           case OID_PKCS_PBESHA128RC4: oid_hex = OID_PKCS_PBESHA128RC4_HEX; break;
554 0           case OID_PKCS_PBESHA40RC4: oid_hex = OID_PKCS_PBESHA40RC4_HEX; break;
555 10           case OID_PKCS_PBESHA3DES3: oid_hex = OID_PKCS_PBESHA3DES3_HEX; break;
556 0           case OID_PKCS_PBESHA2DES3: oid_hex = OID_PKCS_PBESHA2DES3_HEX; break;
557 0           case OID_PKCS_PBESHA128RC2: oid_hex = OID_PKCS_PBESHA128RC2_HEX; break;
558 14           case OID_PKCS_PBESHA40RC2: oid_hex = OID_PKCS_PBESHA40RC2_HEX; break;
559 0           case OID_PKCS12_BAG_TYPE_KEY: oid_hex = OID_PKCS12_BAG_TYPE_KEY_HEX; break;
560 10           case OID_PKCS12_BAG_TYPE_SHROUD: oid_hex = OID_PKCS12_BAG_TYPE_SHROUD_HEX; break;
561 11           case OID_PKCS12_BAG_TYPE_CERT: oid_hex = OID_PKCS12_BAG_TYPE_CERT_HEX; break;
562 0           case OID_PKCS12_BAG_TYPE_CRL: oid_hex = OID_PKCS12_BAG_TYPE_CRL_HEX; break;
563 0           case OID_PKCS12_BAG_TYPE_SECRET: oid_hex = OID_PKCS12_BAG_TYPE_SECRET_HEX; break;
564 0           case OID_PKCS12_BAG_TYPE_SAFE: oid_hex = OID_PKCS12_BAG_TYPE_SAFE_HEX; break;
565 11           case OID_PKCS9_CERT_TYPE_X509: oid_hex = OID_PKCS9_CERT_TYPE_X509_HEX; break;
566 0           case OID_PKCS9_CERT_TYPE_SDSI: oid_hex = OID_PKCS9_CERT_TYPE_SDSI_HEX; break;
567 38           case OID_PKCS7_DATA: oid_hex = OID_PKCS7_DATA_HEX; break;
568 0           case OID_PKCS7_SIGNED_DATA: oid_hex = OID_PKCS7_SIGNED_DATA_HEX; break;
569 0           case OID_PKCS7_ENVELOPED_DATA: oid_hex = OID_PKCS7_ENVELOPED_DATA_HEX; break;
570 0           case OID_PKCS7_SIGNED_ENVELOPED_DATA: oid_hex = OID_PKCS7_SIGNED_ENVELOPED_DATA_HEX; break;
571 4858           case OID_PKCS7_DIGESTED_DATA: oid_hex = OID_PKCS7_DIGESTED_DATA_HEX; break;
572 74           case OID_PKCS7_ENCRYPTED_DATA: oid_hex = OID_PKCS7_ENCRYPTED_DATA_HEX; break;
573 0           case OID_OCSP: oid_hex = OID_OCSP_HEX; break;
574 0           case OID_BASIC_OCSP_RESPONSE: oid_hex = OID_BASIC_OCSP_RESPONSE_HEX; break;
575 0           case OID_ECKA_EG_X963KDF_SHA256: oid_hex = OID_ECKA_EG_X963KDF_SHA256_HEX; break;
576 0           case OID_ECKA_EG_X963KDF_SHA384: oid_hex = OID_ECKA_EG_X963KDF_SHA384_HEX; break;
577 0           case OID_ECKA_EG_X963KDF_SHA512: oid_hex = OID_ECKA_EG_X963KDF_SHA512_HEX; break;
578 0           case OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME_HEX; break;
579 0           case OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME_HEX; break;
580 0           case OID_MQVSINGLEPASS_SHA1KDF_SCHEME: oid_hex = OID_MQVSINGLEPASS_SHA1KDF_SCHEME_HEX; break;
581 0           case OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME_HEX; break;
582 0           case OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME_HEX; break;
583 0           case OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME_HEX; break;
584             default:
585             /* No possible matches: bitwise-add not found constant to OID. */
586 0           *oi |= OID_NOT_FOUND;
587 0           return;
588             }
589             /* Ignore tag, but use length byte and data from binary oid. */
590 16648 100         if (oidLen == oid_hex[1] && !memcmp(oidStart, &oid_hex[2], oidLen))
    100          
591             {
592 11100           return; /* Success */
593             }
594 5548           *oi += OID_COLLISION;
595 5548           }
596             }
597             #endif /* MATRIXSSL_NO_OID_DATABASE */
598              
599             /******************************************************************************/
600              
601 11100           int32_t getAsnOID(const unsigned char **pp, uint32_t len, int32_t *oi,
602             uint8_t checkForParams, psSize_t *paramLen)
603             {
604 11100           const unsigned char *p = *pp, *end;
605             int32_t plen, rc;
606             uint32_t arcLen;
607             const unsigned char *oidStart;
608             uint32_t oidLen;
609              
610 11100           rc = PS_PARSE_FAIL;
611 11100           end = p + len;
612 11100           plen = end - p;
613 11100 50         if (*(p++) != ASN_OID || (rc = getAsnLength32(&p, (uint32_t) (end - p), &arcLen, 0))
    50          
614             < 0)
615             {
616             psTraceCrypto("Malformed algorithmId 2\n");
617 0           return rc;
618             }
619 11100 50         if (end - p < arcLen)
620             {
621 0           return PS_LIMIT_FAIL;
622             }
623 11100 50         if (end - p < 2)
624             {
625             psTraceCrypto("Malformed algorithmId 3\n");
626 0           return PS_LIMIT_FAIL;
627             }
628 11100           *oi = 0;
629 11100           oidStart = p;
630 11100           oidLen = arcLen;
631 110617 100         while (arcLen > 0)
632             {
633 99517           *oi += *p;
634 99517           p++;
635 99517           arcLen--;
636             }
637              
638             #ifndef MATRIXSSL_NO_OID_DATABASE
639 11100           checkAsnOidDatabase(oi, oidStart, oidLen);
640             #endif /* MATRIXSSL_NO_OID_DATABASE */
641              
642 11100 50         if (checkForParams)
643             {
644 11100           plen -= (end - p);
645 11100           *paramLen = len - plen;
646 11100 100         if (*p != ASN_NULL)
647             {
648 423           *pp = p;
649             /* paramLen tells whether params exist or completely missing (0) */
650 423           if (*paramLen > 0)
651             {
652             /* psTraceIntCrypto("OID %d has parameters to process\n", *oi); */
653             }
654 423           return PS_SUCCESS;
655             }
656             /* NULL parameter case. Somewhat common. Skip it for the caller */
657 10677 50         if (end - p < 2)
658             {
659             psTraceCrypto("Malformed algorithmId 4\n");
660 0           return PS_LIMIT_FAIL;
661             }
662 10677 50         if (*paramLen < 2)
663             {
664             psTraceCrypto("Malformed algorithmId 5\n");
665 0           return PS_LIMIT_FAIL;
666             }
667 10677           *paramLen -= 2; /* 1 for the OID tag and 1 for the NULL */
668 10677           *pp = p + 2;
669             }
670             else
671             {
672 0           *paramLen = 0;
673 0           *pp = p;
674             }
675 11100           return PS_SUCCESS;
676             }
677              
678             /******************************************************************************/
679