2 * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
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
11 #include "internal/cryptlib.h"
12 #include "internal/numbers.h"
13 #include <openssl/asn1t.h>
14 #include <openssl/bn.h>
15 #include "asn1_locl.h"
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.
24 * We abuse the ASN1_ITEM fields |size| as a flags field
26 #define INTxx_FLAG_ZERO_DEFAULT (1<<0)
27 #define INTxx_FLAG_SIGNED (1<<1)
29 static int uint64_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
31 *(uint64_t *)pval = 0;
35 static void uint64_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
37 *(uint64_t *)pval = 0;
40 static int uint64_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
45 /* this exists to bypass broken gcc optimization */
46 char *cp = (char *)pval;
48 /* use memcpy, because we may not be uint64_t aligned */
49 memcpy(&utmp, cp, sizeof(utmp));
51 if ((it->size & INTxx_FLAG_ZERO_DEFAULT) == INTxx_FLAG_ZERO_DEFAULT
54 if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
58 return i2c_uint64_int(cont, utmp, neg);
61 static int uint64_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
62 int utype, char *free_cont, const ASN1_ITEM *it)
65 char *cp = (char *)pval;
68 if (!c2i_uint64_int(&utmp, &neg, &cont, len))
70 if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) {
71 ASN1err(ASN1_F_UINT64_C2I, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
74 memcpy(cp, &utmp, sizeof(utmp));
78 static int uint64_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
79 int indent, const ASN1_PCTX *pctx)
81 if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED)
82 return BIO_printf(out, "%jd\n", *(int64_t *)pval);
83 return BIO_printf(out, "%ju\n", *(uint64_t *)pval);
88 static int uint32_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
90 *(uint32_t *)pval = 0;
94 static void uint32_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
96 *(uint32_t *)pval = 0;
99 static int uint32_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
104 /* this exists to bypass broken gcc optimization */
105 char *cp = (char *)pval;
107 /* use memcpy, because we may not be uint32_t aligned */
108 memcpy(&utmp, cp, sizeof(utmp));
110 if ((it->size & INTxx_FLAG_ZERO_DEFAULT) == INTxx_FLAG_ZERO_DEFAULT
113 if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
114 && (int32_t)utmp < 0)
117 return i2c_uint64_int(cont, (uint64_t)utmp, neg);
120 static int uint32_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
121 int utype, char *free_cont, const ASN1_ITEM *it)
125 char *cp = (char *)pval;
128 if (!c2i_uint64_int(&utmp, &neg, &cont, len))
130 if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) {
131 ASN1err(ASN1_F_UINT32_C2I, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
134 utmp2 = (uint32_t)utmp;
136 || ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
137 && !neg && utmp2 > INT32_MAX)) {
138 ASN1err(ASN1_F_UINT32_C2I, ASN1_R_TOO_LARGE);
141 memcpy(cp, &utmp2, sizeof(utmp2));
145 static int uint32_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
146 int indent, const ASN1_PCTX *pctx)
148 if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED)
149 return BIO_printf(out, "%d\n", *(int32_t *)pval);
150 return BIO_printf(out, "%u\n", *(uint32_t *)pval);
154 /* Define the primitives themselves */
156 static ASN1_PRIMITIVE_FUNCS uint32_pf = {
160 uint32_free, /* Clear should set to initial value */
166 static ASN1_PRIMITIVE_FUNCS uint64_pf = {
170 uint64_free, /* Clear should set to initial value */
176 ASN1_ITEM_start(INT32)
177 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
178 INTxx_FLAG_SIGNED, "INT32"
181 ASN1_ITEM_start(UINT32)
182 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf, 0, "UINT32"
183 ASN1_ITEM_end(UINT32)
185 ASN1_ITEM_start(INT64)
186 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
187 INTxx_FLAG_SIGNED, "INT64"
190 ASN1_ITEM_start(UINT64)
191 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf, 0, "UINT64"
192 ASN1_ITEM_end(UINT64)
194 ASN1_ITEM_start(ZINT32)
195 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
196 INTxx_FLAG_ZERO_DEFAULT|INTxx_FLAG_SIGNED, "ZINT32"
197 ASN1_ITEM_end(ZINT32)
199 ASN1_ITEM_start(ZUINT32)
200 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
201 INTxx_FLAG_ZERO_DEFAULT, "ZUINT32"
202 ASN1_ITEM_end(ZUINT32)
204 ASN1_ITEM_start(ZINT64)
205 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
206 INTxx_FLAG_ZERO_DEFAULT|INTxx_FLAG_SIGNED, "ZINT64"
207 ASN1_ITEM_end(ZINT64)
209 ASN1_ITEM_start(ZUINT64)
210 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
211 INTxx_FLAG_ZERO_DEFAULT, "ZUINT64"
212 ASN1_ITEM_end(ZUINT64)