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
)