Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/bearssl/src/ec/ecdsa_atr.c
39488 views
1
/*
2
* Copyright (c) 2016 Thomas Pornin <[email protected]>
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining
5
* a copy of this software and associated documentation files (the
6
* "Software"), to deal in the Software without restriction, including
7
* without limitation the rights to use, copy, modify, merge, publish,
8
* distribute, sublicense, and/or sell copies of the Software, and to
9
* permit persons to whom the Software is furnished to do so, subject to
10
* the following conditions:
11
*
12
* The above copyright notice and this permission notice shall be
13
* included in all copies or substantial portions of the Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
* SOFTWARE.
23
*/
24
25
#include "inner.h"
26
27
/* see bearssl_ec.h */
28
size_t
29
br_ecdsa_asn1_to_raw(void *sig, size_t sig_len)
30
{
31
/*
32
* Note: this code is a bit lenient in that it accepts a few
33
* deviations to DER with regards to minimality of encoding of
34
* lengths and integer values. These deviations are still
35
* unambiguous.
36
*
37
* Signature format is a SEQUENCE of two INTEGER values. We
38
* support only integers of less than 127 bytes each (signed
39
* encoding) so the resulting raw signature will have length
40
* at most 254 bytes.
41
*/
42
43
unsigned char *buf, *r, *s;
44
size_t zlen, rlen, slen, off;
45
unsigned char tmp[254];
46
47
buf = sig;
48
if (sig_len < 8) {
49
return 0;
50
}
51
52
/*
53
* First byte is SEQUENCE tag.
54
*/
55
if (buf[0] != 0x30) {
56
return 0;
57
}
58
59
/*
60
* The SEQUENCE length will be encoded over one or two bytes. We
61
* limit the total SEQUENCE contents to 255 bytes, because it
62
* makes things simpler; this is enough for subgroup orders up
63
* to 999 bits.
64
*/
65
zlen = buf[1];
66
if (zlen > 0x80) {
67
if (zlen != 0x81) {
68
return 0;
69
}
70
zlen = buf[2];
71
if (zlen != sig_len - 3) {
72
return 0;
73
}
74
off = 3;
75
} else {
76
if (zlen != sig_len - 2) {
77
return 0;
78
}
79
off = 2;
80
}
81
82
/*
83
* First INTEGER (r).
84
*/
85
if (buf[off ++] != 0x02) {
86
return 0;
87
}
88
rlen = buf[off ++];
89
if (rlen >= 0x80) {
90
return 0;
91
}
92
r = buf + off;
93
off += rlen;
94
95
/*
96
* Second INTEGER (s).
97
*/
98
if (off + 2 > sig_len) {
99
return 0;
100
}
101
if (buf[off ++] != 0x02) {
102
return 0;
103
}
104
slen = buf[off ++];
105
if (slen >= 0x80 || slen != sig_len - off) {
106
return 0;
107
}
108
s = buf + off;
109
110
/*
111
* Removing leading zeros from r and s.
112
*/
113
while (rlen > 0 && *r == 0) {
114
rlen --;
115
r ++;
116
}
117
while (slen > 0 && *s == 0) {
118
slen --;
119
s ++;
120
}
121
122
/*
123
* Compute common length for the two integers, then copy integers
124
* into the temporary buffer, and finally copy it back over the
125
* signature buffer.
126
*/
127
zlen = rlen > slen ? rlen : slen;
128
sig_len = zlen << 1;
129
memset(tmp, 0, sig_len);
130
memcpy(tmp + zlen - rlen, r, rlen);
131
memcpy(tmp + sig_len - slen, s, slen);
132
memcpy(sig, tmp, sig_len);
133
return sig_len;
134
}
135
136