diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib/libcrypto/asn1/asn1_lib.c | 204 |
1 files changed, 0 insertions, 204 deletions
diff --git a/src/lib/libcrypto/asn1/asn1_lib.c b/src/lib/libcrypto/asn1/asn1_lib.c deleted file mode 100644 index ac8da0e61d..0000000000 --- a/src/lib/libcrypto/asn1/asn1_lib.c +++ /dev/null | |||
@@ -1,204 +0,0 @@ | |||
1 | /* $OpenBSD: asn1_lib.c,v 1.54 2022/05/05 19:18:56 jsing Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2021 Joel Sing <jsing@openbsd.org> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #include <limits.h> | ||
19 | #include <stdlib.h> | ||
20 | |||
21 | #include "bytestring.h" | ||
22 | |||
23 | int | ||
24 | asn1_get_identifier_cbs(CBS *cbs, int der_mode, uint8_t *out_class, | ||
25 | int *out_constructed, uint32_t *out_tag_number) | ||
26 | { | ||
27 | uint8_t tag_class, tag_val; | ||
28 | int tag_constructed; | ||
29 | uint32_t tag_number; | ||
30 | |||
31 | /* | ||
32 | * Decode ASN.1 identifier octets - see ITU-T X.690 section 8.1.2. | ||
33 | */ | ||
34 | |||
35 | *out_class = 0; | ||
36 | *out_constructed = 0; | ||
37 | *out_tag_number = 0; | ||
38 | |||
39 | if (!CBS_get_u8(cbs, &tag_val)) | ||
40 | return 0; | ||
41 | |||
42 | /* | ||
43 | * ASN.1 tag class, encoding (primitive or constructed) and tag number | ||
44 | * are encoded in one or more identifier octets - the first octet | ||
45 | * contains the 2 bit tag class, the 1 bit encoding type and 5 bits | ||
46 | * of tag number. | ||
47 | * | ||
48 | * For tag numbers larger than 30 (0x1e) the 5 bit tag number in the | ||
49 | * first octet is set to all ones (0x1f) - the tag number is then | ||
50 | * encoded in subsequent octets - each of which have a one bit | ||
51 | * continuation flag and 7 bits of tag number in big-endian form. | ||
52 | * The encoding should not contain leading zeros but can for BER. | ||
53 | */ | ||
54 | tag_class = (tag_val >> 6) & 0x3; | ||
55 | tag_constructed = (tag_val >> 5) & 0x1; | ||
56 | tag_number = tag_val & 0x1f; | ||
57 | |||
58 | /* Long form. */ | ||
59 | if (tag_number == 0x1f) { | ||
60 | tag_number = 0; | ||
61 | do { | ||
62 | if (!CBS_get_u8(cbs, &tag_val)) | ||
63 | return 0; | ||
64 | if (der_mode && tag_number == 0 && tag_val == 0x80) | ||
65 | return 0; | ||
66 | if (tag_number > (UINT32_MAX >> 7)) | ||
67 | return 0; | ||
68 | tag_number = tag_number << 7 | (tag_val & 0x7f); | ||
69 | } while ((tag_val & 0x80) != 0); | ||
70 | } | ||
71 | |||
72 | *out_class = tag_class; | ||
73 | *out_constructed = tag_constructed; | ||
74 | *out_tag_number = tag_number; | ||
75 | |||
76 | return 1; | ||
77 | } | ||
78 | |||
79 | int | ||
80 | asn1_get_length_cbs(CBS *cbs, int der_mode, int *out_indefinite, | ||
81 | size_t *out_length) | ||
82 | { | ||
83 | uint8_t len_bytes; | ||
84 | size_t length; | ||
85 | uint8_t val; | ||
86 | |||
87 | /* | ||
88 | * Decode ASN.1 length octets - see ITU-T X.690 section 8.1.3. | ||
89 | */ | ||
90 | |||
91 | *out_length = 0; | ||
92 | *out_indefinite = 0; | ||
93 | |||
94 | if (!CBS_get_u8(cbs, &val)) | ||
95 | return 0; | ||
96 | |||
97 | /* | ||
98 | * Short form - length is encoded in the lower 7 bits of a single byte. | ||
99 | */ | ||
100 | if (val < 0x80) { | ||
101 | *out_length = val; | ||
102 | return 1; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * Indefinite length - content continues until an End of Content (EOC) | ||
107 | * marker is reached. Must be used with constructed encoding. | ||
108 | */ | ||
109 | if (val == 0x80) { | ||
110 | *out_indefinite = 1; | ||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * Long form - the lower 7 bits of the first byte specifies the number | ||
116 | * of bytes used to encode the length, the following bytes specify the | ||
117 | * length in big-endian form. The encoding should not contain leading | ||
118 | * zeros but can for BER. A length value of 0x7f is invalid. | ||
119 | */ | ||
120 | if ((len_bytes = val & 0x7f) == 0x7f) | ||
121 | return 0; | ||
122 | |||
123 | length = 0; | ||
124 | |||
125 | while (len_bytes-- > 0) { | ||
126 | if (!CBS_get_u8(cbs, &val)) | ||
127 | return 0; | ||
128 | if (der_mode && length == 0 && val == 0) | ||
129 | return 0; | ||
130 | if (length > (SIZE_MAX >> 8)) | ||
131 | return 0; | ||
132 | length = (length << 8) | val; | ||
133 | } | ||
134 | |||
135 | *out_length = length; | ||
136 | |||
137 | return 1; | ||
138 | } | ||
139 | |||
140 | int | ||
141 | asn1_get_object_cbs(CBS *cbs, int der_mode, uint8_t *out_tag_class, | ||
142 | int *out_constructed, uint32_t *out_tag_number, int *out_indefinite, | ||
143 | size_t *out_length) | ||
144 | { | ||
145 | int constructed, indefinite; | ||
146 | uint32_t tag_number; | ||
147 | uint8_t tag_class; | ||
148 | size_t length; | ||
149 | |||
150 | *out_tag_class = 0; | ||
151 | *out_constructed = 0; | ||
152 | *out_tag_number = 0; | ||
153 | *out_indefinite = 0; | ||
154 | *out_length = 0; | ||
155 | |||
156 | if (!asn1_get_identifier_cbs(cbs, der_mode, &tag_class, &constructed, | ||
157 | &tag_number)) | ||
158 | return 0; | ||
159 | if (!asn1_get_length_cbs(cbs, der_mode, &indefinite, &length)) | ||
160 | return 0; | ||
161 | |||
162 | /* Indefinite length can only be used with constructed encoding. */ | ||
163 | if (indefinite && !constructed) | ||
164 | return 0; | ||
165 | |||
166 | *out_tag_class = tag_class; | ||
167 | *out_constructed = constructed; | ||
168 | *out_tag_number = tag_number; | ||
169 | *out_indefinite = indefinite; | ||
170 | *out_length = length; | ||
171 | |||
172 | return 1; | ||
173 | } | ||
174 | |||
175 | int | ||
176 | asn1_get_primitive(CBS *cbs, int der_mode, uint32_t *out_tag_number, | ||
177 | CBS *out_content) | ||
178 | { | ||
179 | int constructed, indefinite; | ||
180 | uint32_t tag_number; | ||
181 | uint8_t tag_class; | ||
182 | size_t length; | ||
183 | |||
184 | *out_tag_number = 0; | ||
185 | |||
186 | CBS_init(out_content, NULL, 0); | ||
187 | |||
188 | if (!asn1_get_identifier_cbs(cbs, der_mode, &tag_class, &constructed, | ||
189 | &tag_number)) | ||
190 | return 0; | ||
191 | if (!asn1_get_length_cbs(cbs, der_mode, &indefinite, &length)) | ||
192 | return 0; | ||
193 | |||
194 | /* A primitive is not constructed and has a definite length. */ | ||
195 | if (constructed || indefinite) | ||
196 | return 0; | ||
197 | |||
198 | if (!CBS_get_bytes(cbs, out_content, length)) | ||
199 | return 0; | ||
200 | |||
201 | *out_tag_number = tag_number; | ||
202 | |||
203 | return 1; | ||
204 | } | ||