-
Notifications
You must be signed in to change notification settings - Fork 1
/
der.c
96 lines (87 loc) · 1.8 KB
/
der.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <string.h>
#include "x509cert.h"
#include "inner.h"
static size_t
encode_len(size_t len, unsigned char *buf)
{
size_t x;
int n, i;
if (len < 0x80) {
if (buf)
buf[0] = len;
return 1;
}
for (x = len, n = 0; x; x >>= 8, ++n)
;
if (buf) {
*buf++ = 0x80 | n;
for (i = n - 1; i >= 0; --i)
*buf++ = len >> (i << 3);
}
return 1 + n;
}
size_t
x509cert_copy(const unsigned char *oid, unsigned char *buf)
{
size_t len = 2 + oid[1];
if (buf)
memcpy(buf, oid, len);
return len;
}
size_t
x509cert_encode(const struct x509cert_item *item, unsigned char *buf)
{
unsigned char *pos;
if (item->enc)
return item->enc(item, buf);
if (item->tag == 0) {
if (buf)
memcpy(buf, item->val, item->len);
return item->len;
}
if (!buf)
return 1 + encode_len(item->len, NULL) + item->len;
pos = buf;
*pos++ = item->tag;
pos += encode_len(item->len, pos);
if (item->val) {
memcpy(pos, item->val, item->len);
pos += item->len;
}
return pos - buf;
}
/*
* Encode an unsigned ASN.1 INTEGER into a buffer.
*
* This routine is separate from x509cert_encode since it has to account
* for a zero-length integer, or one with the most-significant bit
* set.
*/
static size_t
encode_uint(const struct x509cert_item *uint, unsigned char *buf)
{
struct x509cert_item item = {X509CERT_ASN1_INTEGER};
int pad;
unsigned char *pos;
size_t len;
pad = uint->len == 0 || *(unsigned char *)uint->val & 0x80;
item.len = uint->len + pad;
len = x509cert_encode(&item, buf);
if (!buf)
return len;
pos = buf + len;
if (pad)
*pos++ = 0;
memcpy(pos, uint->val, uint->len);
pos += uint->len;
return pos - buf;
}
void
x509cert_uint(struct x509cert_item *item, const unsigned char *buf, size_t len)
{
while (len > 0 && buf[0] == 0)
--len, ++buf;
item->len = len;
item->val = buf;
item->enc = encode_uint;
}