commit eed9cd3
V. Luna
·
2026-10-08 05:09:05 +0000 UTC
parent 67f7ae9
parse spki
3 files changed,
+83,
-29
M
Makefile
+1,
-1
1@@ -11,7 +11,7 @@ snac: snac.o main.o sandbox.o data.o http.o httpd.o webfinger.o \
2 test: tests/b64_vectors
3
4 tests/b64_vectors: tests/b64_vectors.o
5- $(CC) $(CFLAGS) -L$(PREFIX)/lib tests/b64_vectors.o $(LDFLAGS) -o $@
6+ $(CC) $(CFLAGS) -L$(PREFIX)/lib -L/home/v/opt/bearssl/lib tests/b64_vectors.o -lbearssl $(LDFLAGS) -o $@
7
8 .c.o:
9 $(CC) $(CFLAGS) $(CPPFLAGS) -I$(PREFIX)/include -I/home/v/opt/bearssl/include -c $< -o $@
+0,
-0
+82,
-28
1@@ -4,10 +4,25 @@
2 #include "xs.h"
3 #include "xs_hex.h"
4
5+xs_str* _xs_digest(const xs_val* input, int size, const char* digest, int as_hex);
6+
7+#ifndef _XS_MD5_H
8+#define xs_md5_hex(input, size) _xs_digest(input, size, "md5", 1)
9+#endif // _XS_MD5_H
10+
11 #ifndef _XS_BASE64_H
12-xs_str* xs_base64_enc(const xs_val *data, int size);
13+xs_str* xs_base64_enc(const xs_val* data, int size);
14+xs_val* xs_base64_dec(const xs_str* data, int* size);
15 #endif // _XS_BASE64_H
16
17+#define xs_sha1_hex(input, size) _xs_digest(input, size, "sha1", 1)
18+#define xs_sha256_hex(input, size) _xs_digest(input, size, "sha256", 1)
19+#define xs_sha256_base64(input, size) _xs_digest(input, size, "sha256", 0)
20+
21+xs_dict* xs_evp_genkey(int bits);
22+xs_str* xs_evp_sign(const char* secret, const char* mem, int size);
23+int xs_evp_verify(const char* pubkey, const char* mem, int size, const char* b64_sig);
24+
25 #ifdef XS_IMPLEMENTATION
26
27 #include "bearssl_x509.h"
28@@ -79,18 +94,26 @@ xs_val* xs_base64_dec(const xs_str* data, int* size) {
29 int input_len = strlen(data);
30 unsigned char* out = xs_realloc(NULL, _xs_blk_size(input_len + 1));
31
32- int o = 0, acc = 0, bits = 0, i;
33+ int o = 0, acc = 0, bits = 0, pad = 0, i;
34
35 for (i = 0; i < input_len; i++) {
36 int c = (unsigned char)data[i];
37 int v;
38
39- if (c == '=' || c == '\n' || c == '\r' || c == ' ' || c == '\t') {
40+ if (c == '\n' || c == '\r' || c == ' ' || c == '\t') {
41 continue;
42 }
43
44+ if (c == '=') {
45+ pad++;
46+ if (pad > 2) { xs_free(out); return NULL; }
47+ continue;
48+ }
49+
50+ if (pad > 0) { xs_free(out); return NULL; }
51+
52 v = _b64_val(c);
53- if (v < 0) { continue; }
54+ if (v < 0) { xs_free(out); return NULL; }
55
56 acc = (acc << 6) | v;
57 bits += 6;
58@@ -101,6 +124,8 @@ xs_val* xs_base64_dec(const xs_str* data, int* size) {
59 }
60 }
61
62+ if (bits != pad * 2) { xs_free(out); return NULL; }
63+
64 out = xs_realloc(out, _xs_blk_size(o + 1));
65 out[o] = '\0';
66 *size = o;
67@@ -205,36 +230,36 @@ static unsigned char* _pem_to_der(const char* pem, size_t* out_len) {
68 return buf.ptr;
69 }
70
71-static int _der_tlv(const unsigned char* p[], const unsigned char* end, unsigned char* tag, size_t* len, const unsigned char* val[]) {
72- const unsigned char *b = *p;
73- size_t l;
74+static int _der_tlv(const unsigned char** cur, const unsigned char* end, unsigned char* tag, size_t* len, const unsigned char** val) {
75+ const unsigned char* p = *cur;
76+ size_t vlen;
77
78- if (b >= end) { return 0; }
79+ if (p >= end) { return 0; }
80
81- *tag = *b++;
82+ *tag = *p++;
83
84- if (b >= end) { return 0; }
85+ if (p >= end) { return 0; }
86
87- l = *b++;
88+ vlen = *p++;
89
90- if (l & 0x80) {
91- int nb = l & 0x7f;
92+ if (vlen & 0x80) {
93+ int nbytes = vlen & 0x7f;
94
95- if (nb == 0 || nb > 4) {return 0; }
96+ if (nbytes == 0 || nbytes > 4) { return 0; }
97
98- l = 0;
99- while (nb--) {
100- if (b >= end) { return 0; }
101+ vlen = 0;
102+ while (nbytes--) {
103+ if (p >= end) { return 0; }
104
105- l = (l << 8) | *b++;
106+ vlen = (vlen << 8) | *p++;
107 }
108 }
109
110- if ((size_t)(end - b) < l) { return 0; }
111+ if ((size_t)(end - p) < vlen) { return 0; }
112
113- *len = l;
114- *val = b;
115- *p = b + l;
116+ *len = vlen;
117+ *val = p;
118+ *cur = p + vlen;
119
120 return 1;
121 }
122@@ -284,16 +309,44 @@ static size_t _der_uint(unsigned char *dst, const unsigned char *v, size_t len)
123 return _der_put(dst, 0x02, tmp, clen);
124 }
125
126-// TODO: this
127 static int _parse_spki(const unsigned char* der, size_t len, br_rsa_public_key* pk) {
128- const unsigned char* p = der, *end = der + len;
129- const unsigned char* v;
130+ const unsigned char* cur = der, *end = der + len;
131+ const unsigned char* val;
132 unsigned char tag;
133- size_t l;
134+ size_t vlen;
135
136- // if (!der_tlv(&p))
137+ // outer SEQUENCE
138+ if (!_der_tlv(&cur, end, &tag, &vlen, &val) || tag != 0x30) { return 0; }
139
140- return 0;
141+ const unsigned char* algo = val, *algo_end = val + vlen;
142+
143+ // AlgorithmIdentifier SEQUENCE
144+ if (!_der_tlv(&algo, algo_end, &tag, &vlen, &val) || tag != 0x30) { return 0; }
145+
146+ // OID (rsaEncryption)
147+ const unsigned char* oid = val, *oid_end = val + vlen;
148+ if (!_der_tlv(&oid, oid_end, &tag, &vlen, &val) || tag != 0x06) { return 0; }
149+
150+ // BIT STRING
151+ if (!_der_tlv(&algo, algo_end, &tag, &vlen, &val) || tag != 0x03) { return 0; }
152+ if (vlen < 1 || val[0] != 0) { return 0; }
153+
154+ const unsigned char* rsa = val + 1, *rsa_end = val + vlen;
155+
156+ // RSAPublicKey SEQUENCE
157+ if (!_der_tlv(&rsa, rsa_end, &tag, &vlen, &val) || tag != 0x30) { return 0; }
158+
159+ const unsigned char* key = val, *key_end = val + vlen;
160+ const unsigned char* n_ptr, *e_ptr;
161+ size_t n_len, e_len;
162+
163+ if (!_der_tlv(&key, key_end, &tag, &n_len, &n_ptr) || tag != 0x02) { return 0; }
164+ if (!_der_tlv(&key, key_end, &tag, &e_len, &e_ptr) || tag != 0x02) { return 0; }
165+
166+ pk->n = (unsigned char*)n_ptr; pk->nlen = n_len;
167+ pk->e = (unsigned char*)e_ptr; pk->elen = e_len;
168+
169+ return 1;
170 }
171
172 /* RSA sign / verify / keygen */
173@@ -347,6 +400,7 @@ int xs_evp_verify(const char* pubkey, const char* mem, int size, const char* b64
174 }
175
176 // TODO:
177+ return 0;
178 }
179
180 #endif // XS_IMPLEMENTATION