diff options
author | jsing <> | 2017-11-28 16:51:21 +0000 |
---|---|---|
committer | jsing <> | 2017-11-28 16:51:21 +0000 |
commit | de5ca2b5f99a16f432ca4cc02b4ac5d82c930283 (patch) | |
tree | 31e83649b4b3312b92b05b2241fc00baf0de2a44 | |
parent | 9d2e79481e8236db55e7cef6b5df7e7a5c9f021b (diff) | |
download | openbsd-de5ca2b5f99a16f432ca4cc02b4ac5d82c930283.tar.gz openbsd-de5ca2b5f99a16f432ca4cc02b4ac5d82c930283.tar.bz2 openbsd-de5ca2b5f99a16f432ca4cc02b4ac5d82c930283.zip |
Rewrite ASN1_TYPE_{get,set}_octetstring() using templated ASN.1.
This removes the last remaining use of the old M_ASN1_* macros (asn1_mac.h)
from API that needs to continue to exist.
ok beck@ inoguchi@
-rw-r--r-- | src/lib/libcrypto/asn1/evp_asn1.c | 159 |
1 files changed, 78 insertions, 81 deletions
diff --git a/src/lib/libcrypto/asn1/evp_asn1.c b/src/lib/libcrypto/asn1/evp_asn1.c index 83228bb5d2..5f74da1546 100644 --- a/src/lib/libcrypto/asn1/evp_asn1.c +++ b/src/lib/libcrypto/asn1/evp_asn1.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: evp_asn1.c,v 1.19 2017/01/29 17:49:22 beck Exp $ */ | 1 | /* $OpenBSD: evp_asn1.c,v 1.20 2017/11/28 16:51:21 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 | * |
@@ -60,7 +60,7 @@ | |||
60 | #include <string.h> | 60 | #include <string.h> |
61 | 61 | ||
62 | #include <openssl/asn1.h> | 62 | #include <openssl/asn1.h> |
63 | #include <openssl/asn1_mac.h> | 63 | #include <openssl/asn1t.h> |
64 | #include <openssl/err.h> | 64 | #include <openssl/err.h> |
65 | 65 | ||
66 | int | 66 | int |
@@ -78,7 +78,6 @@ ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len) | |||
78 | return (1); | 78 | return (1); |
79 | } | 79 | } |
80 | 80 | ||
81 | /* int max_len: for returned value */ | ||
82 | int | 81 | int |
83 | ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len) | 82 | ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len) |
84 | { | 83 | { |
@@ -100,101 +99,99 @@ ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len) | |||
100 | return (ret); | 99 | return (ret); |
101 | } | 100 | } |
102 | 101 | ||
102 | typedef struct { | ||
103 | ASN1_INTEGER *num; | ||
104 | ASN1_OCTET_STRING *value; | ||
105 | } ASN1_int_octetstring; | ||
106 | |||
107 | static const ASN1_TEMPLATE ASN1_INT_OCTETSTRING_seq_tt[] = { | ||
108 | { | ||
109 | .offset = offsetof(ASN1_int_octetstring, num), | ||
110 | .field_name = "num", | ||
111 | .item = &ASN1_INTEGER_it, | ||
112 | }, | ||
113 | { | ||
114 | .offset = offsetof(ASN1_int_octetstring, value), | ||
115 | .field_name = "value", | ||
116 | .item = &ASN1_OCTET_STRING_it, | ||
117 | }, | ||
118 | }; | ||
119 | |||
120 | const ASN1_ITEM ASN1_INT_OCTETSTRING_it = { | ||
121 | .itype = ASN1_ITYPE_SEQUENCE, | ||
122 | .utype = V_ASN1_SEQUENCE, | ||
123 | .templates = ASN1_INT_OCTETSTRING_seq_tt, | ||
124 | .tcount = sizeof(ASN1_INT_OCTETSTRING_seq_tt) / sizeof(ASN1_TEMPLATE), | ||
125 | .size = sizeof(ASN1_int_octetstring), | ||
126 | .sname = "ASN1_INT_OCTETSTRING", | ||
127 | }; | ||
128 | |||
103 | int | 129 | int |
104 | ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data, | 130 | ASN1_TYPE_set_int_octetstring(ASN1_TYPE *at, long num, unsigned char *data, |
105 | int len) | 131 | int len) |
106 | { | 132 | { |
107 | int n, size; | 133 | ASN1_int_octetstring *ios; |
108 | ASN1_OCTET_STRING os, *osp; | 134 | ASN1_STRING *sp = NULL; |
109 | ASN1_INTEGER in; | 135 | int ret = 0; |
110 | unsigned char *p; | ||
111 | unsigned char buf[32]; /* when they have 256bit longs, | ||
112 | * I'll be in trouble */ | ||
113 | in.data = buf; | ||
114 | in.length = 32; | ||
115 | os.data = data; | ||
116 | os.type = V_ASN1_OCTET_STRING; | ||
117 | os.length = len; | ||
118 | ASN1_INTEGER_set(&in, num); | ||
119 | n = i2d_ASN1_INTEGER(&in, NULL); | ||
120 | n += i2d_ASN1_bytes((ASN1_STRING *)&os, NULL, V_ASN1_OCTET_STRING, | ||
121 | V_ASN1_UNIVERSAL); | ||
122 | |||
123 | size = ASN1_object_size(1, n, V_ASN1_SEQUENCE); | ||
124 | |||
125 | if ((osp = ASN1_STRING_new()) == NULL) | ||
126 | return (0); | ||
127 | /* Grow the 'string' */ | ||
128 | if (!ASN1_STRING_set(osp, NULL, size)) { | ||
129 | ASN1_STRING_free(osp); | ||
130 | return (0); | ||
131 | } | ||
132 | 136 | ||
133 | ASN1_STRING_length_set(osp, size); | 137 | if ((ios = (ASN1_int_octetstring *)ASN1_item_new( |
134 | p = ASN1_STRING_data(osp); | 138 | &ASN1_INT_OCTETSTRING_it)) == NULL) |
139 | goto err; | ||
140 | if ((ios->num = ASN1_INTEGER_new()) == NULL) | ||
141 | goto err; | ||
142 | if (!ASN1_INTEGER_set(ios->num, num)) | ||
143 | goto err; | ||
144 | if ((ios->value = ASN1_OCTET_STRING_new()) == NULL) | ||
145 | goto err; | ||
146 | if (!ASN1_OCTET_STRING_set(ios->value, data, len)) | ||
147 | goto err; | ||
135 | 148 | ||
136 | ASN1_put_object(&p, 1,n, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); | 149 | if ((sp = ASN1_item_pack(ios, &ASN1_INT_OCTETSTRING_it, NULL)) == NULL) |
137 | i2d_ASN1_INTEGER(&in, &p); | 150 | goto err; |
138 | i2d_ASN1_bytes((ASN1_STRING *)&os, &p, V_ASN1_OCTET_STRING, | ||
139 | V_ASN1_UNIVERSAL); | ||
140 | 151 | ||
141 | ASN1_TYPE_set(a, V_ASN1_SEQUENCE, osp); | 152 | ASN1_TYPE_set(at, V_ASN1_SEQUENCE, sp); |
142 | return (1); | 153 | sp = NULL; |
154 | |||
155 | ret = 1; | ||
156 | |||
157 | err: | ||
158 | ASN1_item_free((ASN1_VALUE *)ios, &ASN1_INT_OCTETSTRING_it); | ||
159 | ASN1_STRING_free(sp); | ||
160 | |||
161 | return ret; | ||
143 | } | 162 | } |
144 | 163 | ||
145 | /* we return the actual length..., num may be missing, in which | ||
146 | * case, set it to zero */ | ||
147 | /* int max_len: for returned value */ | ||
148 | int | 164 | int |
149 | ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, unsigned char *data, | 165 | ASN1_TYPE_get_int_octetstring(ASN1_TYPE *at, long *num, unsigned char *data, |
150 | int max_len) | 166 | int max_len) |
151 | { | 167 | { |
152 | int ret = -1, n; | 168 | ASN1_STRING *sp = at->value.sequence; |
153 | ASN1_INTEGER *ai = NULL; | 169 | ASN1_int_octetstring *ios = NULL; |
154 | ASN1_OCTET_STRING *os = NULL; | 170 | int ret = -1; |
155 | const unsigned char *p; | 171 | int len; |
156 | long length; | ||
157 | ASN1_const_CTX c; | ||
158 | |||
159 | if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) { | ||
160 | goto err; | ||
161 | } | ||
162 | p = ASN1_STRING_data(a->value.sequence); | ||
163 | length = ASN1_STRING_length(a->value.sequence); | ||
164 | 172 | ||
165 | c.pp = &p; | 173 | if (at->type != V_ASN1_SEQUENCE || sp == NULL) |
166 | c.p = p; | ||
167 | c.max = p + length; | ||
168 | c.error = ASN1_R_DATA_IS_WRONG; | ||
169 | |||
170 | M_ASN1_D2I_start_sequence(); | ||
171 | c.q = c.p; | ||
172 | if ((ai = d2i_ASN1_INTEGER(NULL, &c.p, c.slen)) == NULL) | ||
173 | goto err; | ||
174 | c.slen -= (c.p - c.q); | ||
175 | c.q = c.p; | ||
176 | if ((os = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL) | ||
177 | goto err; | 174 | goto err; |
178 | c.slen -= (c.p - c.q); | 175 | |
179 | if (!M_ASN1_D2I_end_sequence()) | 176 | if ((ios = ASN1_item_unpack(sp, &ASN1_INT_OCTETSTRING_it)) == NULL) |
180 | goto err; | 177 | goto err; |
181 | 178 | ||
182 | if (num != NULL) | 179 | if (num != NULL) |
183 | *num = ASN1_INTEGER_get(ai); | 180 | *num = ASN1_INTEGER_get(ios->num); |
181 | if (data != NULL) { | ||
182 | len = ASN1_STRING_length(ios->value); | ||
183 | if (len > max_len) | ||
184 | len = max_len; | ||
185 | memcpy(data, ASN1_STRING_data(ios->value), len); | ||
186 | } | ||
184 | 187 | ||
185 | ret = ASN1_STRING_length(os); | 188 | ret = ASN1_STRING_length(ios->value); |
186 | if (max_len > ret) | 189 | |
187 | n = ret; | 190 | err: |
188 | else | 191 | ASN1_item_free((ASN1_VALUE *)ios, &ASN1_INT_OCTETSTRING_it); |
189 | n = max_len; | ||
190 | 192 | ||
191 | if (data != NULL) | 193 | if (ret == -1) |
192 | memcpy(data, ASN1_STRING_data(os), n); | ||
193 | if (0) { | ||
194 | err: | ||
195 | ASN1error(ASN1_R_DATA_IS_WRONG); | 194 | ASN1error(ASN1_R_DATA_IS_WRONG); |
196 | } | 195 | |
197 | ASN1_OCTET_STRING_free(os); | 196 | return ret; |
198 | ASN1_INTEGER_free(ai); | ||
199 | return (ret); | ||
200 | } | 197 | } |