commit eed9cd3

V. Luna  ·  2026-10-08 05:09:05 +0000 UTC
parent 67f7ae9
parse spki
3 files changed,  +83, -29
+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