diff options
Diffstat (limited to '')
| -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 | } |
