summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2017-11-28 16:51:21 +0000
committerjsing <>2017-11-28 16:51:21 +0000
commitde5ca2b5f99a16f432ca4cc02b4ac5d82c930283 (patch)
tree31e83649b4b3312b92b05b2241fc00baf0de2a44
parent9d2e79481e8236db55e7cef6b5df7e7a5c9f021b (diff)
downloadopenbsd-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.c159
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
66int 66int
@@ -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 */
82int 81int
83ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len) 82ASN1_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
102typedef struct {
103 ASN1_INTEGER *num;
104 ASN1_OCTET_STRING *value;
105} ASN1_int_octetstring;
106
107static 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
120const 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
103int 129int
104ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data, 130ASN1_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 */
148int 164int
149ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, unsigned char *data, 165ASN1_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) {
194err:
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}