diff options
Diffstat (limited to 'src/lib/libcrypto/asn1/asn1_old_lib.c')
-rw-r--r-- | src/lib/libcrypto/asn1/asn1_old_lib.c | 129 |
1 files changed, 40 insertions, 89 deletions
diff --git a/src/lib/libcrypto/asn1/asn1_old_lib.c b/src/lib/libcrypto/asn1/asn1_old_lib.c index cc9a48f74c..958c15b30c 100644 --- a/src/lib/libcrypto/asn1/asn1_old_lib.c +++ b/src/lib/libcrypto/asn1/asn1_old_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: asn1_old_lib.c,v 1.1 2021/12/15 18:12:10 jsing Exp $ */ | 1 | /* $OpenBSD: asn1_old_lib.c,v 1.2 2021/12/25 07:04:03 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -63,7 +63,8 @@ | |||
63 | #include <openssl/asn1.h> | 63 | #include <openssl/asn1.h> |
64 | #include <openssl/err.h> | 64 | #include <openssl/err.h> |
65 | 65 | ||
66 | static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max); | 66 | #include "asn1_locl.h" |
67 | |||
67 | static void asn1_put_length(unsigned char **pp, int length); | 68 | static void asn1_put_length(unsigned char **pp, int length); |
68 | 69 | ||
69 | static int | 70 | static int |
@@ -96,101 +97,51 @@ int | |||
96 | ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, | 97 | ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, |
97 | int *pclass, long omax) | 98 | int *pclass, long omax) |
98 | { | 99 | { |
99 | int i, ret; | 100 | int constructed, indefinite; |
100 | long l; | 101 | uint32_t tag_number, length; |
101 | const unsigned char *p = *pp; | 102 | uint8_t tag_class; |
102 | int tag, xclass, inf; | 103 | CBS cbs; |
103 | long max = omax; | 104 | int ret = 0; |
104 | 105 | ||
105 | if (!max) | 106 | *pclass = 0; |
106 | goto err; | 107 | *ptag = 0; |
107 | ret = (*p & V_ASN1_CONSTRUCTED); | 108 | *plength = 0; |
108 | xclass = (*p & V_ASN1_PRIVATE); | 109 | |
109 | i = *p & V_ASN1_PRIMITIVE_TAG; | 110 | CBS_init(&cbs, *pp, omax); |
110 | if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */ | 111 | |
111 | p++; | 112 | if (!asn1_get_object_cbs(&cbs, 0, &tag_class, &constructed, &tag_number, |
112 | if (--max == 0) | 113 | &indefinite, &length)) { |
113 | goto err; | 114 | ASN1error(ASN1_R_HEADER_TOO_LONG); |
114 | l = 0; | 115 | return 0x80; |
115 | while (*p & 0x80) { | ||
116 | l <<= 7L; | ||
117 | l |= *(p++) & 0x7f; | ||
118 | if (--max == 0) | ||
119 | goto err; | ||
120 | if (l > (INT_MAX >> 7L)) | ||
121 | goto err; | ||
122 | } | ||
123 | l <<= 7L; | ||
124 | l |= *(p++) & 0x7f; | ||
125 | tag = (int)l; | ||
126 | if (--max == 0) | ||
127 | goto err; | ||
128 | } else { | ||
129 | tag = i; | ||
130 | p++; | ||
131 | if (--max == 0) | ||
132 | goto err; | ||
133 | } | 116 | } |
134 | *ptag = tag; | ||
135 | *pclass = xclass; | ||
136 | if (!asn1_get_length(&p, &inf, plength, (int)max)) | ||
137 | goto err; | ||
138 | 117 | ||
139 | if (inf && !(ret & V_ASN1_CONSTRUCTED)) | 118 | if (tag_number > INT_MAX) { |
140 | goto err; | 119 | ASN1error(ASN1_R_HEADER_TOO_LONG); |
120 | return 0x80; | ||
121 | } | ||
141 | 122 | ||
142 | if (*plength > (omax - (p - *pp))) { | 123 | /* |
124 | * API insanity ahead... in this case we add an error to the stack and | ||
125 | * signal an error by setting the 8th bit in the return value... but we | ||
126 | * still provide all of the decoded data. | ||
127 | */ | ||
128 | if (length > CBS_len(&cbs)) { | ||
143 | ASN1error(ASN1_R_TOO_LONG); | 129 | ASN1error(ASN1_R_TOO_LONG); |
144 | /* Set this so that even if things are not long enough | 130 | ret = 0x80; |
145 | * the values are set correctly */ | ||
146 | ret |= 0x80; | ||
147 | } | 131 | } |
148 | *pp = p; | ||
149 | return (ret | inf); | ||
150 | 132 | ||
151 | err: | 133 | *pclass = tag_class << 6; |
152 | ASN1error(ASN1_R_HEADER_TOO_LONG); | 134 | *ptag = tag_number; |
153 | return (0x80); | 135 | *plength = length; |
154 | } | ||
155 | 136 | ||
156 | static int | 137 | *pp = CBS_data(&cbs); |
157 | asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max) | ||
158 | { | ||
159 | const unsigned char *p = *pp; | ||
160 | unsigned long ret = 0; | ||
161 | unsigned int i; | ||
162 | 138 | ||
163 | if (max-- < 1) | 139 | if (constructed) |
164 | return (0); | 140 | ret |= 1 << 5; |
165 | if (*p == 0x80) { | 141 | if (indefinite) |
166 | *inf = 1; | 142 | ret |= 1; |
167 | ret = 0; | 143 | |
168 | p++; | 144 | return ret; |
169 | } else { | ||
170 | *inf = 0; | ||
171 | i = *p & 0x7f; | ||
172 | if (*(p++) & 0x80) { | ||
173 | if (max < (int)i) | ||
174 | return (0); | ||
175 | /* skip leading zeroes */ | ||
176 | while (i && *p == 0) { | ||
177 | p++; | ||
178 | i--; | ||
179 | } | ||
180 | if (i > sizeof(long)) | ||
181 | return 0; | ||
182 | while (i-- > 0) { | ||
183 | ret <<= 8L; | ||
184 | ret |= *(p++); | ||
185 | } | ||
186 | } else | ||
187 | ret = i; | ||
188 | } | ||
189 | if (ret > LONG_MAX) | ||
190 | return 0; | ||
191 | *pp = p; | ||
192 | *rl = (long)ret; | ||
193 | return (1); | ||
194 | } | 145 | } |
195 | 146 | ||
196 | /* class 0 is constructed | 147 | /* class 0 is constructed |