OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | 4 |
5 /* | 5 /* |
6 * Support for DEcoding ASN.1 data based on BER/DER (Basic/Distinguished | 6 * Support for DEcoding ASN.1 data based on BER/DER (Basic/Distinguished |
7 * Encoding Rules). | 7 * Encoding Rules). |
8 */ | 8 */ |
9 | 9 |
10 /* #define DEBUG_ASN1D_STATES 1 */ | 10 /* #define DEBUG_ASN1D_STATES 1 */ |
11 | 11 |
12 #ifdef DEBUG_ASN1D_STATES | 12 #ifdef DEBUG_ASN1D_STATES |
13 #include <stdio.h> | 13 #include <stdio.h> |
14 #define PR_Assert sec_asn1d_Assert | 14 #define PR_Assert sec_asn1d_Assert |
15 #endif | 15 #endif |
16 | 16 |
| 17 #include <limits.h> |
| 18 |
17 #include "secasn1.h" | 19 #include "secasn1.h" |
18 #include "secerr.h" | 20 #include "secerr.h" |
19 | 21 |
20 typedef enum { | 22 typedef enum { |
21 beforeIdentifier, | 23 beforeIdentifier, |
22 duringIdentifier, | 24 duringIdentifier, |
23 afterIdentifier, | 25 afterIdentifier, |
24 beforeLength, | 26 beforeLength, |
25 duringLength, | 27 duringLength, |
26 afterLength, | 28 afterLength, |
(...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1586 return 0; | 1588 return 0; |
1587 } | 1589 } |
1588 | 1590 |
1589 if (state->pending < len) | 1591 if (state->pending < len) |
1590 len = state->pending; | 1592 len = state->pending; |
1591 | 1593 |
1592 bufLen = len; | 1594 bufLen = len; |
1593 | 1595 |
1594 item = (SECItem *)(state->dest); | 1596 item = (SECItem *)(state->dest); |
1595 if (item != NULL && item->data != NULL) { | 1597 if (item != NULL && item->data != NULL) { |
| 1598 unsigned long offset; |
1596 /* Strip leading zeroes when target is unsigned integer */ | 1599 /* Strip leading zeroes when target is unsigned integer */ |
1597 if (state->underlying_kind == SEC_ASN1_INTEGER && /* INTEGER */ | 1600 if (state->underlying_kind == SEC_ASN1_INTEGER && /* INTEGER */ |
1598 item->len == 0 && /* MSB */ | 1601 item->len == 0 && /* MSB */ |
1599 item->type == siUnsignedInteger) /* unsigned */ | 1602 item->type == siUnsignedInteger) /* unsigned */ |
1600 { | 1603 { |
1601 while (len > 1 && buf[0] == 0) { /* leading 0 */ | 1604 while (len > 1 && buf[0] == 0) { /* leading 0 */ |
1602 buf++; | 1605 buf++; |
1603 len--; | 1606 len--; |
1604 } | 1607 } |
1605 } | 1608 } |
1606 » PORT_Memcpy (item->data + item->len, buf, len); | 1609 offset = item->len; |
1607 » item->len += len; | 1610 if (state->underlying_kind == SEC_ASN1_BIT_STRING) { |
| 1611 // The previous bit string must have no unused bits. |
| 1612 if (item->len & 0x7) { |
| 1613 PORT_SetError (SEC_ERROR_BAD_DER); |
| 1614 state->top->status = decodeError; |
| 1615 return 0; |
| 1616 } |
| 1617 // If this is a bit string, the length is bits, not bytes. |
| 1618 offset = item->len >> 3; |
| 1619 } |
| 1620 if (state->underlying_kind == SEC_ASN1_BIT_STRING) { |
| 1621 unsigned long len_in_bits; |
| 1622 // Protect against overflow during the bytes-to-bits conversion. |
| 1623 if (len >= (ULONG_MAX >> 3) + 1) { |
| 1624 PORT_SetError (SEC_ERROR_BAD_DER); |
| 1625 state->top->status = decodeError; |
| 1626 return 0; |
| 1627 } |
| 1628 len_in_bits = (len << 3) - state->bit_string_unused_bits; |
| 1629 // Protect against overflow when computing the total length in bits. |
| 1630 if (UINT_MAX - item->len < len_in_bits) { |
| 1631 PORT_SetError (SEC_ERROR_BAD_DER); |
| 1632 state->top->status = decodeError; |
| 1633 return 0; |
| 1634 } |
| 1635 item->len += len_in_bits; |
| 1636 } else { |
| 1637 if (UINT_MAX - item->len < len) { |
| 1638 PORT_SetError (SEC_ERROR_BAD_DER); |
| 1639 state->top->status = decodeError; |
| 1640 return 0; |
| 1641 } |
| 1642 item->len += len; |
| 1643 } |
| 1644 PORT_Memcpy (item->data + offset, buf, len); |
1608 } | 1645 } |
1609 state->pending -= bufLen; | 1646 state->pending -= bufLen; |
1610 if (state->pending == 0) | 1647 if (state->pending == 0) |
1611 state->place = beforeEndOfContents; | 1648 state->place = beforeEndOfContents; |
1612 | 1649 |
1613 return bufLen; | 1650 return bufLen; |
1614 } | 1651 } |
1615 | 1652 |
1616 | 1653 |
1617 static unsigned long | 1654 static unsigned long |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1664 PORT_SetError (SEC_ERROR_BAD_DER); | 1701 PORT_SetError (SEC_ERROR_BAD_DER); |
1665 state->top->status = decodeError; | 1702 state->top->status = decodeError; |
1666 } else { | 1703 } else { |
1667 /* An empty bit string with no unused bits is OK. */ | 1704 /* An empty bit string with no unused bits is OK. */ |
1668 state->place = beforeEndOfContents; | 1705 state->place = beforeEndOfContents; |
1669 } | 1706 } |
1670 return 0; | 1707 return 0; |
1671 } | 1708 } |
1672 | 1709 |
1673 len = sec_asn1d_parse_leaf (state, buf, len); | 1710 len = sec_asn1d_parse_leaf (state, buf, len); |
1674 if (state->place == beforeEndOfContents && state->dest != NULL) { | |
1675 SECItem *item; | |
1676 | |
1677 item = (SECItem *)(state->dest); | |
1678 if (item->len) | |
1679 item->len = (item->len << 3) - state->bit_string_unused_bits; | |
1680 } | |
1681 | |
1682 return len; | 1711 return len; |
1683 } | 1712 } |
1684 | 1713 |
1685 | 1714 |
1686 /* | 1715 /* |
1687 * XXX All callers should be looking at return value to detect | 1716 * XXX All callers should be looking at return value to detect |
1688 * out-of-memory errors (and stop!). | 1717 * out-of-memory errors (and stop!). |
1689 */ | 1718 */ |
1690 static struct subitem * | 1719 static struct subitem * |
1691 sec_asn1d_add_to_subitems (sec_asn1d_state *state, | 1720 sec_asn1d_add_to_subitems (sec_asn1d_state *state, |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2201 item_len = 0; | 2230 item_len = 0; |
2202 is_bit_string = (state->underlying_kind == SEC_ASN1_BIT_STRING) | 2231 is_bit_string = (state->underlying_kind == SEC_ASN1_BIT_STRING) |
2203 ? PR_TRUE : PR_FALSE; | 2232 ? PR_TRUE : PR_FALSE; |
2204 | 2233 |
2205 substring = state->subitems_head; | 2234 substring = state->subitems_head; |
2206 while (substring != NULL) { | 2235 while (substring != NULL) { |
2207 /* | 2236 /* |
2208 * All bit-string substrings except the last one should be | 2237 * All bit-string substrings except the last one should be |
2209 * a clean multiple of 8 bits. | 2238 * a clean multiple of 8 bits. |
2210 */ | 2239 */ |
2211 » if (is_bit_string && (substring->next == NULL) | 2240 » if (is_bit_string && (substring->next != NULL) |
2212 && (substring->len & 0x7)) { | 2241 && (substring->len & 0x7)) { |
2213 PORT_SetError (SEC_ERROR_BAD_DER); | 2242 PORT_SetError (SEC_ERROR_BAD_DER); |
2214 state->top->status = decodeError; | 2243 state->top->status = decodeError; |
2215 return; | 2244 return; |
2216 } | 2245 } |
2217 item_len += substring->len; | 2246 item_len += substring->len; |
2218 substring = substring->next; | 2247 substring = substring->next; |
2219 } | 2248 } |
2220 | 2249 |
2221 if (is_bit_string) { | 2250 if (is_bit_string) { |
(...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3394 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_EnumeratedTemplate) | 3423 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_EnumeratedTemplate) |
3395 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PointerToEnumeratedTemplate) | 3424 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PointerToEnumeratedTemplate) |
3396 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SequenceOfAnyTemplate) | 3425 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SequenceOfAnyTemplate) |
3397 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SequenceOfObjectIDTemplate) | 3426 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SequenceOfObjectIDTemplate) |
3398 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SkipTemplate) | 3427 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SkipTemplate) |
3399 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_UniversalStringTemplate) | 3428 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_UniversalStringTemplate) |
3400 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PrintableStringTemplate) | 3429 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PrintableStringTemplate) |
3401 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_T61StringTemplate) | 3430 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_T61StringTemplate) |
3402 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PointerToGeneralizedTimeTemplate) | 3431 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PointerToGeneralizedTimeTemplate) |
3403 | 3432 |
OLD | NEW |