1/* 2 * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10#include <stdio.h> 11#include "internal/cryptlib.h" 12#include "internal/numbers.h" 13#include <openssl/asn1t.h> 14#include <openssl/bn.h> 15#include "asn1_local.h" 16 17/* 18 * Custom primitive types for handling int32_t, int64_t, uint32_t, uint64_t. 19 * This converts between an ASN1_INTEGER and those types directly. 20 * This is preferred to using the LONG / ZLONG primitives. 21 */ 22 23/* 24 * We abuse the ASN1_ITEM fields |size| as a flags field 25 */ 26#define INTxx_FLAG_ZERO_DEFAULT (1<<0) 27#define INTxx_FLAG_SIGNED (1<<1) 28 29static int uint64_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 30{ 31 if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint64_t))) == NULL) { 32 ASN1err(ASN1_F_UINT64_NEW, ERR_R_MALLOC_FAILURE); 33 return 0; 34 } 35 return 1; 36} 37 38static void uint64_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 39{ 40 OPENSSL_free(*pval); 41 *pval = NULL; 42} 43 44static void uint64_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 45{ 46 **(uint64_t **)pval = 0; 47} 48 49static int uint64_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, 50 const ASN1_ITEM *it) 51{ 52 uint64_t utmp; 53 int neg = 0; 54 /* this exists to bypass broken gcc optimization */ 55 char *cp = (char *)*pval; 56 57 /* use memcpy, because we may not be uint64_t aligned */ 58 memcpy(&utmp, cp, sizeof(utmp)); 59 60 if ((it->size & INTxx_FLAG_ZERO_DEFAULT) == INTxx_FLAG_ZERO_DEFAULT 61 && utmp == 0) 62 return -1; 63 if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED 64 && (int64_t)utmp < 0) { 65 /* i2c_uint64_int() assumes positive values */ 66 utmp = 0 - utmp; 67 neg = 1; 68 } 69 70 return i2c_uint64_int(cont, utmp, neg); 71} 72 73static int uint64_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, 74 int utype, char *free_cont, const ASN1_ITEM *it) 75{ 76 uint64_t utmp = 0; 77 char *cp; 78 int neg = 0; 79 80 if (*pval == NULL && !uint64_new(pval, it)) 81 return 0; 82 83 cp = (char *)*pval; 84 85 /* 86 * Strictly speaking, zero length is malformed. However, long_c2i 87 * (x_long.c) encodes 0 as a zero length INTEGER (wrongly, of course), 88 * so for the sake of backward compatibility, we still decode zero 89 * length INTEGERs as the number zero. 90 */ 91 if (len == 0) 92 goto long_compat; 93 94 if (!c2i_uint64_int(&utmp, &neg, &cont, len)) 95 return 0; 96 if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) { 97 ASN1err(ASN1_F_UINT64_C2I, ASN1_R_ILLEGAL_NEGATIVE_VALUE); 98 return 0; 99 } 100 if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED 101 && !neg && utmp > INT64_MAX) { 102 ASN1err(ASN1_F_UINT64_C2I, ASN1_R_TOO_LARGE); 103 return 0; 104 } 105 if (neg) 106 /* c2i_uint64_int() returns positive values */ 107 utmp = 0 - utmp; 108 109 long_compat: 110 memcpy(cp, &utmp, sizeof(utmp)); 111 return 1; 112} 113 114static int uint64_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, 115 int indent, const ASN1_PCTX *pctx) 116{ 117 if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED) 118 return BIO_printf(out, "%jd\n", **(int64_t **)pval); 119 return BIO_printf(out, "%ju\n", **(uint64_t **)pval); 120} 121 122/* 32-bit variants */ 123 124static int uint32_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 125{ 126 if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint32_t))) == NULL) { 127 ASN1err(ASN1_F_UINT32_NEW, ERR_R_MALLOC_FAILURE); 128 return 0; 129 } 130 return 1; 131} 132 133static void uint32_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 134{ 135 OPENSSL_free(*pval); 136 *pval = NULL; 137} 138 139static void uint32_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 140{ 141 **(uint32_t **)pval = 0; 142} 143 144static int uint32_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, 145 const ASN1_ITEM *it) 146{ 147 uint32_t utmp; 148 int neg = 0; 149 /* this exists to bypass broken gcc optimization */ 150 char *cp = (char *)*pval; 151 152 /* use memcpy, because we may not be uint32_t aligned */ 153 memcpy(&utmp, cp, sizeof(utmp)); 154 155 if ((it->size & INTxx_FLAG_ZERO_DEFAULT) == INTxx_FLAG_ZERO_DEFAULT 156 && utmp == 0) 157 return -1; 158 if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED 159 && (int32_t)utmp < 0) { 160 /* i2c_uint64_int() assumes positive values */ 161 utmp = 0 - utmp; 162 neg = 1; 163 } 164 165 return i2c_uint64_int(cont, (uint64_t)utmp, neg); 166} 167 168/* 169 * Absolute value of INT32_MIN: we can't just use -INT32_MIN as it produces 170 * overflow warnings. 171 */ 172 173#define ABS_INT32_MIN ((uint32_t)INT32_MAX + 1) 174 175static int uint32_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, 176 int utype, char *free_cont, const ASN1_ITEM *it) 177{ 178 uint64_t utmp = 0; 179 uint32_t utmp2 = 0; 180 char *cp; 181 int neg = 0; 182 183 if (*pval == NULL && !uint64_new(pval, it)) 184 return 0; 185 186 cp = (char *)*pval; 187 188 /* 189 * Strictly speaking, zero length is malformed. However, long_c2i 190 * (x_long.c) encodes 0 as a zero length INTEGER (wrongly, of course), 191 * so for the sake of backward compatibility, we still decode zero 192 * length INTEGERs as the number zero. 193 */ 194 if (len == 0) 195 goto long_compat; 196 197 if (!c2i_uint64_int(&utmp, &neg, &cont, len)) 198 return 0; 199 if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) { 200 ASN1err(ASN1_F_UINT32_C2I, ASN1_R_ILLEGAL_NEGATIVE_VALUE); 201 return 0; 202 } 203 if (neg) { 204 if (utmp > ABS_INT32_MIN) { 205 ASN1err(ASN1_F_UINT32_C2I, ASN1_R_TOO_SMALL); 206 return 0; 207 } 208 utmp = 0 - utmp; 209 } else { 210 if (((it->size & INTxx_FLAG_SIGNED) != 0 && utmp > INT32_MAX) 211 || ((it->size & INTxx_FLAG_SIGNED) == 0 && utmp > UINT32_MAX)) { 212 ASN1err(ASN1_F_UINT32_C2I, ASN1_R_TOO_LARGE); 213 return 0; 214 } 215 } 216 217 long_compat: 218 utmp2 = (uint32_t)utmp; 219 memcpy(cp, &utmp2, sizeof(utmp2)); 220 return 1; 221} 222 223static int uint32_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, 224 int indent, const ASN1_PCTX *pctx) 225{ 226 if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED) 227 return BIO_printf(out, "%d\n", **(int32_t **)pval); 228 return BIO_printf(out, "%u\n", **(uint32_t **)pval); 229} 230 231 232/* Define the primitives themselves */ 233 234static ASN1_PRIMITIVE_FUNCS uint32_pf = { 235 NULL, 0, 236 uint32_new, 237 uint32_free, 238 uint32_clear, 239 uint32_c2i, 240 uint32_i2c, 241 uint32_print 242}; 243 244static ASN1_PRIMITIVE_FUNCS uint64_pf = { 245 NULL, 0, 246 uint64_new, 247 uint64_free, 248 uint64_clear, 249 uint64_c2i, 250 uint64_i2c, 251 uint64_print 252}; 253 254ASN1_ITEM_start(INT32) 255 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf, 256 INTxx_FLAG_SIGNED, "INT32" 257ASN1_ITEM_end(INT32) 258 259ASN1_ITEM_start(UINT32) 260 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf, 0, "UINT32" 261ASN1_ITEM_end(UINT32) 262 263ASN1_ITEM_start(INT64) 264 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf, 265 INTxx_FLAG_SIGNED, "INT64" 266ASN1_ITEM_end(INT64) 267 268ASN1_ITEM_start(UINT64) 269 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf, 0, "UINT64" 270ASN1_ITEM_end(UINT64) 271 272ASN1_ITEM_start(ZINT32) 273 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf, 274 INTxx_FLAG_ZERO_DEFAULT|INTxx_FLAG_SIGNED, "ZINT32" 275ASN1_ITEM_end(ZINT32) 276 277ASN1_ITEM_start(ZUINT32) 278 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf, 279 INTxx_FLAG_ZERO_DEFAULT, "ZUINT32" 280ASN1_ITEM_end(ZUINT32) 281 282ASN1_ITEM_start(ZINT64) 283 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf, 284 INTxx_FLAG_ZERO_DEFAULT|INTxx_FLAG_SIGNED, "ZINT64" 285ASN1_ITEM_end(ZINT64) 286 287ASN1_ITEM_start(ZUINT64) 288 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf, 289 INTxx_FLAG_ZERO_DEFAULT, "ZUINT64" 290ASN1_ITEM_end(ZUINT64) 291 292