]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/asn1/x_int64.c
Update dtlstest to use the test infrastructure
[thirdparty/openssl.git] / crypto / asn1 / x_int64.c
CommitLineData
93f7d6fc
RL
1/*
2 * Copyright 2017 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"
93f7d6fc 12#include "internal/numbers.h"
64f11ee8 13#include <openssl/asn1t.h>
93f7d6fc
RL
14#include <openssl/bn.h>
15#include "asn1_locl.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 *(uint64_t *)pval = 0;
32 return 1;
33}
34
35static void uint64_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
36{
37 *(uint64_t *)pval = 0;
38}
39
40static int uint64_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
41 const ASN1_ITEM *it)
42{
43 uint64_t utmp;
44 int neg = 0;
45 /* this exists to bypass broken gcc optimization */
46 char *cp = (char *)pval;
47
48 /* use memcpy, because we may not be uint64_t aligned */
49 memcpy(&utmp, cp, sizeof(utmp));
50
51 if ((it->size & INTxx_FLAG_ZERO_DEFAULT) == INTxx_FLAG_ZERO_DEFAULT
52 && utmp == 0)
53 return -1;
54 if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
55 && (int64_t)utmp < 0)
56 neg = 1;
57
58 return i2c_uint64_int(cont, utmp, neg);
59}
60
61static int uint64_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
62 int utype, char *free_cont, const ASN1_ITEM *it)
63{
64 uint64_t utmp = 0;
65 char *cp = (char *)pval;
66 int neg = 0;
67
68 if (!c2i_uint64_int(&utmp, &neg, &cont, len))
69 return 0;
70 if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) {
71 ASN1err(ASN1_F_UINT64_C2I, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
72 return 0;
73 }
74 memcpy(cp, &utmp, sizeof(utmp));
75 return 1;
76}
77
78static int uint64_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
79 int indent, const ASN1_PCTX *pctx)
80{
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);
84}
85
86/* 32-bit variants */
87
88static int uint32_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
89{
90 *(uint32_t *)pval = 0;
91 return 1;
92}
93
94static void uint32_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
95{
96 *(uint32_t *)pval = 0;
97}
98
99static int uint32_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
100 const ASN1_ITEM *it)
101{
102 uint32_t utmp;
103 int neg = 0;
104 /* this exists to bypass broken gcc optimization */
105 char *cp = (char *)pval;
106
107 /* use memcpy, because we may not be uint32_t aligned */
108 memcpy(&utmp, cp, sizeof(utmp));
109
110 if ((it->size & INTxx_FLAG_ZERO_DEFAULT) == INTxx_FLAG_ZERO_DEFAULT
111 && utmp == 0)
112 return -1;
113 if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
114 && (int32_t)utmp < 0)
115 neg = 1;
116
117 return i2c_uint64_int(cont, (uint64_t)utmp, neg);
118}
119
120static int uint32_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
121 int utype, char *free_cont, const ASN1_ITEM *it)
122{
123 uint64_t utmp = 0;
124 uint32_t utmp2 = 0;
125 char *cp = (char *)pval;
126 int neg = 0;
127
128 if (!c2i_uint64_int(&utmp, &neg, &cont, len))
129 return 0;
130 if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) {
131 ASN1err(ASN1_F_UINT32_C2I, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
132 return 0;
133 }
134 utmp2 = (uint32_t)utmp;
135 if (utmp != utmp2
136 || ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
137 && !neg && utmp2 > INT32_MAX)) {
138 ASN1err(ASN1_F_UINT32_C2I, ASN1_R_TOO_LARGE);
139 return 0;
140 }
141 memcpy(cp, &utmp2, sizeof(utmp2));
142 return 1;
143}
144
145static int uint32_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
146 int indent, const ASN1_PCTX *pctx)
147{
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);
151}
152
153
154/* Define the primitives themselves */
155
156static ASN1_PRIMITIVE_FUNCS uint32_pf = {
157 NULL, 0,
158 uint32_new,
159 uint32_free,
160 uint32_free, /* Clear should set to initial value */
161 uint32_c2i,
162 uint32_i2c,
163 uint32_print
164};
165
166static ASN1_PRIMITIVE_FUNCS uint64_pf = {
167 NULL, 0,
168 uint64_new,
169 uint64_free,
170 uint64_free, /* Clear should set to initial value */
171 uint64_c2i,
172 uint64_i2c,
173 uint64_print
174};
175
176ASN1_ITEM_start(INT32)
177 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
178 INTxx_FLAG_SIGNED, "INT32"
179ASN1_ITEM_end(INT32)
180
181ASN1_ITEM_start(UINT32)
182 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf, 0, "UINT32"
183ASN1_ITEM_end(UINT32)
184
185ASN1_ITEM_start(INT64)
186 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
187 INTxx_FLAG_SIGNED, "INT64"
188ASN1_ITEM_end(INT64)
189
190ASN1_ITEM_start(UINT64)
191 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf, 0, "UINT64"
192ASN1_ITEM_end(UINT64)
193
194ASN1_ITEM_start(ZINT32)
195 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
196 INTxx_FLAG_ZERO_DEFAULT|INTxx_FLAG_SIGNED, "ZINT32"
197ASN1_ITEM_end(ZINT32)
198
199ASN1_ITEM_start(ZUINT32)
200 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
201 INTxx_FLAG_ZERO_DEFAULT, "ZUINT32"
202ASN1_ITEM_end(ZUINT32)
203
204ASN1_ITEM_start(ZINT64)
205 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
206 INTxx_FLAG_ZERO_DEFAULT|INTxx_FLAG_SIGNED, "ZINT64"
207ASN1_ITEM_end(ZINT64)
208
209ASN1_ITEM_start(ZUINT64)
210 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
211 INTxx_FLAG_ZERO_DEFAULT, "ZUINT64"
212ASN1_ITEM_end(ZUINT64)
213