File Coverage

lib/Crypt/Bear.xs
Criterion Covered Total %
statement 549 782 70.2
branch 118 236 50.0
condition n/a
subroutine n/a
pod n/a
total 667 1018 65.5


line stmt bran cond sub pod time code
1             #include
2              
3             #define PERL_NO_GET_CONTEXT
4             #include "EXTERN.h"
5             #include "perl.h"
6             #include "XSUB.h"
7              
8             /* Generic stuff */
9              
10             typedef struct {
11             const char* key;
12             size_t length;
13             union value {
14             const void* pointer;
15             UV integer;
16             } value;
17             } entry;
18             typedef entry map[];
19              
20             #define make_map_int_entry(name, result) { STR_WITH_LEN(name), (union value) { .integer = result } }
21             #define make_map_pointer_entry(name, result) { STR_WITH_LEN(name), (union value) { .pointer = result } }
22              
23 26           static const entry* S_map_find(pTHX_ const map table, size_t table_size, const char* name, size_t name_length) {
24             size_t i;
25 74 50         for (i = 0; i < table_size; ++i) {
26 74 100         if (table[i].length == name_length && strEQ(name, table[i].key))
    100          
27 26           return &table[i];
28             }
29 0           return NULL;
30             }
31             #define map_find(table, table_size, name, name_len) S_map_find(aTHX_ table, table_size, name, name_len)
32              
33 26           static union value S_map_get(pTHX_ const map table, size_t table_size, SV* input, const char* type) {
34             STRLEN name_length;
35 26           const char* name = SvPVutf8(input, name_length);
36 26           const entry* item = map_find(table, table_size, name, name_length);
37 26 50         if (item == NULL)
38 0           Perl_croak(aTHX_ "No such %s '%s'", type, name);
39 26           return item->value;
40             }
41             #define map_get(table, name, type) S_map_get(aTHX_ table, sizeof table / sizeof *table, name, type)
42              
43 2           static const entry* S_map_reverse_find(pTHX_ const map table, size_t table_size, union value value) {
44             size_t i;
45 2 50         for (i = 0; i < table_size; ++i) {
46 2 50         if (memcmp(&table[i].value, &value, sizeof(union value)) == 0)
47 2           return table + i;
48             }
49 0           return NULL;
50             }
51             #define map_reverse_find(table, value) S_map_reverse_find(aTHX_ table, sizeof table / sizeof *table, value)
52              
53 34           static SV* S_make_buffer(pTHX_ size_t size) {
54 34           SV* result = newSVpv(NULL, 0);
55 34 50         SvGROW(result, size);
    50          
56 34           SvPOK_on(result);
57 34           SvCUR_set(result, size);
58 34           return result;
59             }
60             #define make_buffer(size) S_make_buffer(aTHX_ size)
61              
62 4           static SV* S_make_magic(pTHX_ const void* object, const char* classname, const MGVTBL* virtual) {
63 4           SV* result = newSV(0);
64 4           MAGIC* magic = sv_magicext(newSVrv(result, classname), NULL, PERL_MAGIC_ext, virtual, (const char*)object, 0);
65 4           magic->mg_flags |= MGf_DUP;
66 4           return result;
67             }
68             #define make_magic(object, class, virtual) S_make_magic(aTHX_ object, class, virtual)
69              
70             #define saveupvn(ptr, len) (unsigned char*)savepvn((const char*)ptr, len)
71             #define push_isa(child, parent) av_push(get_av(#child "::ISA", GV_ADD), newSVpvs(#parent))
72              
73             #define br_error_entry(name, key) make_map_int_entry(name, BR_ERR_ ## key)
74             static const map br_errors = {
75             // SSL errors
76              
77             br_error_entry("ok", OK),
78             br_error_entry("bad param", BAD_PARAM),
79             br_error_entry("bad state", BAD_STATE),
80             br_error_entry("unsupported version", UNSUPPORTED_VERSION),
81             br_error_entry("bad version", BAD_VERSION),
82             br_error_entry("bad length", BAD_LENGTH),
83             br_error_entry("too large", TOO_LARGE),
84             br_error_entry("bad mac", BAD_MAC),
85             br_error_entry("no random", NO_RANDOM),
86             br_error_entry("unknown type", UNKNOWN_TYPE),
87             br_error_entry("unexpected", UNEXPECTED),
88             br_error_entry("bad ccs", BAD_CCS),
89             br_error_entry("bad alert", BAD_ALERT),
90             br_error_entry("bad handshake", BAD_HANDSHAKE),
91             br_error_entry("oversized id", OVERSIZED_ID),
92             br_error_entry("bad cipher suite", BAD_CIPHER_SUITE),
93             br_error_entry("bad compression", BAD_COMPRESSION),
94             br_error_entry("bad fraglen", BAD_FRAGLEN),
95             br_error_entry("bad secreneg", BAD_SECRENEG),
96             br_error_entry("extra extension", EXTRA_EXTENSION),
97             br_error_entry("bad sni", BAD_SNI),
98             br_error_entry("bad hello done", BAD_HELLO_DONE),
99             br_error_entry("limit exceeded", LIMIT_EXCEEDED),
100             br_error_entry("bad finished", BAD_FINISHED),
101             br_error_entry("resume mismatch", RESUME_MISMATCH),
102             br_error_entry("invalid algorithm", INVALID_ALGORITHM),
103             br_error_entry("bad signature", BAD_SIGNATURE),
104             br_error_entry("wrong key usage", WRONG_KEY_USAGE),
105             br_error_entry("no client auth", NO_CLIENT_AUTH),
106             br_error_entry("io", IO),
107             br_error_entry("recv fatal alert", RECV_FATAL_ALERT),
108             br_error_entry("send fatal alert", SEND_FATAL_ALERT),
109              
110             // X509 errors
111             br_error_entry("ok", X509_OK),
112             br_error_entry("invalid value", X509_INVALID_VALUE),
113             br_error_entry("truncated", X509_TRUNCATED),
114             br_error_entry("empty chain", X509_EMPTY_CHAIN),
115             br_error_entry("inner trunc", X509_INNER_TRUNC),
116             br_error_entry("bad tag class", X509_BAD_TAG_CLASS),
117             br_error_entry("bad tag value", X509_BAD_TAG_VALUE),
118             br_error_entry("indefinite length", X509_INDEFINITE_LENGTH),
119             br_error_entry("extra element", X509_EXTRA_ELEMENT),
120             br_error_entry("unexpected", X509_UNEXPECTED),
121             br_error_entry("not constructed", X509_NOT_CONSTRUCTED),
122             br_error_entry("not primitive", X509_NOT_PRIMITIVE),
123             br_error_entry("partial byte", X509_PARTIAL_BYTE),
124             br_error_entry("bad boolean", X509_BAD_BOOLEAN),
125             br_error_entry("overflow", X509_OVERFLOW),
126             br_error_entry("bad dn", X509_BAD_DN),
127             br_error_entry("bad time", X509_BAD_TIME),
128             br_error_entry("unsupported", X509_UNSUPPORTED),
129             br_error_entry("limit exceeded", X509_LIMIT_EXCEEDED),
130             br_error_entry("wrong key type", X509_WRONG_KEY_TYPE),
131             br_error_entry("bad signature", X509_BAD_SIGNATURE),
132             br_error_entry("time unknown", X509_TIME_UNKNOWN),
133             br_error_entry("expired", X509_EXPIRED),
134             br_error_entry("dn mismatch", X509_DN_MISMATCH),
135             br_error_entry("bad server name", X509_BAD_SERVER_NAME),
136             br_error_entry("critical extension", X509_CRITICAL_EXTENSION),
137             br_error_entry("not ca", X509_NOT_CA),
138             br_error_entry("forbidden key usage", X509_FORBIDDEN_KEY_USAGE),
139             br_error_entry("weak public key", X509_WEAK_PUBLIC_KEY),
140             br_error_entry("not trusted", X509_NOT_TRUSTED),
141              
142             };
143             typedef unsigned br_error_type;
144              
145 0           static const char* S_lookup_error(pTHX_ int error) {
146 0           union value value = { .integer = error };
147 0           const entry* entry = map_reverse_find(br_errors, value);
148 0 0         return entry ? entry->key : NULL;
149             }
150             #define lookup_error(error) S_lookup_error(aTHX_ error)
151              
152              
153             /* Hash stuff */
154              
155             #define hash_entry_for(name) make_map_pointer_entry(#name, (&br_ ## name ## _vtable))
156              
157             static const map hashs = {
158             hash_entry_for(sha256),
159             hash_entry_for(sha512),
160             hash_entry_for(sha384),
161             hash_entry_for(sha224),
162             hash_entry_for(sha1),
163             hash_entry_for(md5)
164             };
165             typedef const br_hash_class* hash_type;
166              
167             typedef const struct hash_oid {
168             size_t length;
169             unsigned char oid[10];
170             } *hash_oid_type;
171             static const struct hash_oid sha1_oid = { 20, { 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A } };
172             static const struct hash_oid sha224_oid = { 28, { 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 } };
173             static const struct hash_oid sha256_oid = { 32, { 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 } };
174             static const struct hash_oid sha384_oid = { 48, { 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 } };
175             static const struct hash_oid sha512_oid = { 64, { 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 } };
176              
177             #define hash_oid_entry(name) make_map_pointer_entry(#name, &name ## _oid)
178             static const map hash_oids = {
179             hash_oid_entry(sha1),
180             hash_oid_entry(sha224),
181             hash_oid_entry(sha256),
182             hash_oid_entry(sha384),
183             hash_oid_entry(sha512),
184             };
185              
186             #define br_hash_update(hasher, data, length) (hasher->vtable->update)(&hasher->vtable, data, length)
187              
188             #define br_hash_desc(hasher, field) (((hasher)->vtable->desc >> BR_HASHDESC_ ## field ## _OFF) & BR_HASHDESC_ ## field ##_MASK)
189             #define br_hash_output_size(hasher) br_hash_desc(hasher, OUT)
190             #define br_hash_state_size(hasher) br_hash_desc(hasher, STATE)
191             #define br_hash_digest(hasher) ((self)->vtable)
192             static br_ghash ghash_impl;
193             #define br_hmac_key_digest br_hmac_key_get_digest
194             #define br_hmac_digest br_hmac_get_digest
195              
196             typedef br_hash_compat_context* Crypt__Bear__Hash;
197             typedef br_hmac_key_context* Crypt__Bear__HMAC__Key;
198             typedef br_hmac_context* Crypt__Bear__HMAC;
199              
200              
201             /* KDF stuff */
202              
203             typedef br_hkdf_context* Crypt__Bear__HKDF;
204             // typedef br_shake_context* Crypt__Bear__Shake;
205              
206             /* Block stuff */
207              
208             static const br_block_cbcenc_class* aes_cbc_enc;
209             static const br_block_cbcdec_class* aes_cbc_dec;
210             static const br_block_ctr_class* aes_ctr;
211             static const br_block_ctrcbc_class* aes_ctrcbc;
212              
213             #define br_block_cbcenc_block_size(cbcenc) (*cbcenc)->block_size
214             #define br_block_cbcdec_block_size(cbcdec) (*cbcdec)->block_size
215             #define br_block_ctr_block_size(ctr) (*ctr)->block_size
216              
217             typedef const br_block_cbcenc_class** Crypt__Bear__CBC__Enc;
218             typedef const br_block_cbcdec_class** Crypt__Bear__CBC__Dec;
219             typedef const br_block_ctr_class** Crypt__Bear__CTR;
220             typedef const br_block_ctrcbc_class** Crypt__Bear__CTRCBC;
221              
222             typedef br_aes_gen_cbcenc_keys* Crypt__Bear__AES_CBC__Enc;
223             typedef br_aes_gen_cbcdec_keys* Crypt__Bear__AES_CBC__Dec;
224             typedef br_aes_gen_ctr_keys* Crypt__Bear__AES_CTR;
225             typedef br_aes_gen_ctrcbc_keys* Crypt__Bear__AES_CTRCBC;
226              
227              
228             /* AEAD stuff */
229              
230             #define br_aead_reset(self, iv, ivlen) ((*(self))->reset)(self, iv, ivlen)
231             #define br_aead_aad_inject(self, ad, adlen) ((*(self))->aad_inject)(self, ad, adlen)
232             #define br_aead_flip(self) ((*(self))->flip)(self)
233             #define br_aead_run(self, encrypt, out, outlen) ((*(self))->run)(self, encrypt, out, outlen)
234             #define br_aead_get_tag(self, buffer) ((*(self))->get_tag)(self, buffer)
235             #define br_aead_check_tag(self, buffer) ((*(self))->check_tag)(self, buffer)
236              
237             typedef const br_aead_class** Crypt__Bear__AEAD;
238             typedef br_gcm_context* Crypt__Bear__GCM;
239             typedef br_eax_context* Crypt__Bear__EAX;
240             typedef br_ccm_context* Crypt__Bear__CCM;
241              
242              
243             /* PRNG stuff */
244              
245             static br_prng_seeder system_seeder;
246             static const char* system_seeder_name;
247             #define br_prng_system_seeder_name(class) system_seeder_name
248             #define br_prng_update(prng, data, length) ((*prng)->update)(prng, data, length)
249             #define br_hmac_drbg_digest br_hmac_drbg_get_hash
250              
251             typedef const br_prng_class** Crypt__Bear__PRNG;
252             typedef br_hmac_drbg_context* Crypt__Bear__HMAC__DRBG;
253             typedef br_aesctr_drbg_context* Crypt__Bear__AES_CTR__DRBG;
254              
255              
256             /* RSA stuff */
257              
258             static br_rsa_pkcs1_vrfy rsa_pkcs1_verify;
259             static br_rsa_pkcs1_sign rsa_pkcs1_sign;
260             static br_rsa_oaep_encrypt rsa_oaep_encrypt;
261             static br_rsa_oaep_decrypt rsa_oaep_decrypt;
262             static br_rsa_keygen br_rsa_generate_keypair;
263              
264 106           static void S_rsa_key_copy(pTHX_ br_rsa_public_key* dest, const br_rsa_public_key* source) {
265 106           char* buffer = safemalloc(source->nlen + source->elen);
266 106           dest->n = memcpy(buffer, source->n, source->nlen);
267 106           dest->nlen = source->nlen;
268 106           buffer += source->nlen;
269 106           dest->e = memcpy(buffer, source->e, source->elen);
270 106           dest->elen = source->elen;
271 106           }
272             #define rsa_key_copy(dest, source) S_rsa_key_copy(aTHX_ dest, source)
273              
274             #define rsa_key_destroy(target) Safefree((target)->n)
275              
276 0           static int rsa_key_dup(pTHX_ MAGIC* magic, CLONE_PARAMS* params) {
277 0           br_rsa_public_key* old = (br_rsa_public_key*)magic->mg_ptr;
278 0           br_rsa_public_key* self = safemalloc(sizeof(br_rsa_public_key));
279 0           rsa_key_copy(self, old);
280 0           magic->mg_ptr = (char*)self;
281 0           return 0;
282             }
283              
284 3           static int rsa_key_free(pTHX_ SV* sv, MAGIC* magic) {
285 3           br_rsa_public_key* self = (br_rsa_public_key*)magic->mg_ptr;
286 3           rsa_key_destroy(self);
287 3           Safefree(self);
288 3           return 0;
289             }
290              
291             static const MGVTBL Crypt__Bear__RSA__PublicKey_magic = {
292             .svt_dup = rsa_key_dup,
293             .svt_free = rsa_key_free,
294             };
295              
296             typedef br_rsa_public_key* Crypt__Bear__RSA__PublicKey;
297              
298 4           static void S_rsa_private_key_copy(pTHX_ br_rsa_private_key* dest, const br_rsa_private_key* source) {
299 4           char* buffer = safemalloc(source->plen + source->qlen + source->dplen + source->dqlen + source->iqlen);
300 4           dest->n_bitlen = source->n_bitlen;
301 4           dest->p = memcpy(buffer, source->p, source->plen);
302 4           dest->plen = source->plen;
303 4           buffer += source->plen;
304 4           dest->q = memcpy(buffer, source->q, source->qlen);
305 4           dest->qlen = source->qlen;
306 4           buffer += source->qlen;
307 4           dest->dp = memcpy(buffer, source->dp, source->dplen);
308 4           dest->dplen = source->dplen;
309 4           buffer += source->dplen;
310 4           dest->dq = memcpy(buffer, source->dq, source->dqlen);
311 4           dest->dqlen = source->dqlen;
312 4           buffer += source->dqlen;
313 4           dest->iq = memcpy(buffer, source->iq, source->iqlen);
314 4           dest->iqlen = source->iqlen;
315 4           buffer += source->iqlen;
316 4           }
317             #define rsa_private_key_copy(dest, source) S_rsa_private_key_copy(aTHX_ dest, source)
318             #define rsa_private_key_destroy(target) Safefree((target)->p)
319              
320 0           static int rsa_private_key_dup(pTHX_ MAGIC* magic, CLONE_PARAMS* params) {
321 0           br_rsa_private_key* old = (br_rsa_private_key*)magic->mg_ptr;
322 0           br_rsa_private_key* self = safemalloc(sizeof(br_rsa_private_key));
323 0           rsa_private_key_copy(self, old);
324 0           magic->mg_ptr = (char*)self;
325 0           return 0;
326             }
327              
328 1           static int rsa_private_key_free(pTHX_ SV* sv, MAGIC* magic) {
329 1           br_rsa_private_key* self = (br_rsa_private_key*)magic->mg_ptr;
330 1           rsa_private_key_destroy(self);
331 1           Safefree(self);
332 1           return 0;
333             }
334              
335             static const MGVTBL Crypt__Bear__RSA__PrivateKey_magic = {
336             .svt_dup = rsa_private_key_dup,
337             .svt_free = rsa_private_key_free,
338             };
339              
340             typedef br_rsa_private_key* Crypt__Bear__RSA__PrivateKey;
341              
342              
343             /* EC stuff */
344              
345             static const size_t ecdsa_max_size = 132;
346              
347             typedef U32 curve_type;
348             #define curve_entry_for(name) make_map_int_entry(#name, BR_EC_ ## name)
349              
350             static const map curves = {
351             curve_entry_for(sect163k1),
352             curve_entry_for(sect163r1),
353             curve_entry_for(sect163r2),
354             curve_entry_for(sect193r1),
355             curve_entry_for(sect193r2),
356             curve_entry_for(sect233k1),
357             curve_entry_for(sect233r1),
358             curve_entry_for(sect239k1),
359             curve_entry_for(sect283k1),
360             curve_entry_for(sect283r1),
361             curve_entry_for(sect409k1),
362             curve_entry_for(sect409r1),
363             curve_entry_for(sect571k1),
364             curve_entry_for(sect571r1),
365              
366             curve_entry_for(secp160k1),
367             curve_entry_for(secp160r1),
368             curve_entry_for(secp160r2),
369             curve_entry_for(secp192k1),
370             curve_entry_for(secp192r1),
371             curve_entry_for(secp224k1),
372             curve_entry_for(secp224r1),
373             curve_entry_for(secp256k1),
374             curve_entry_for(secp256r1),
375             curve_entry_for(secp384r1),
376             curve_entry_for(secp521r1),
377              
378             curve_entry_for(brainpoolP256r1),
379             curve_entry_for(brainpoolP384r1),
380             curve_entry_for(brainpoolP512r1),
381              
382             curve_entry_for(curve25519),
383             curve_entry_for(curve448),
384             };
385              
386 47           static void S_ec_key_copy(pTHX_ br_ec_public_key* dest, const br_ec_public_key* source) {
387 47           dest->curve = source->curve;
388 47           dest->q = saveupvn(source->q, source->qlen);
389 47           dest->qlen = source->qlen;
390 47           }
391             #define ec_key_copy(dest, source) S_ec_key_copy(aTHX_ dest, source)
392              
393             #define ec_key_destroy(key) Safefree((key)->q)
394              
395 0           static int ec_key_dup(pTHX_ MAGIC* magic, CLONE_PARAMS* params) {
396 0           br_ec_public_key* old = (br_ec_public_key*)magic->mg_ptr;
397 0           br_ec_public_key* self = safemalloc(sizeof(br_ec_public_key));
398 0           ec_key_copy(self, old);
399 0           magic->mg_ptr = (char*)self;
400 0           return 0;
401             }
402              
403 4           static int ec_key_free(pTHX_ SV* sv, MAGIC* magic) {
404 4           br_ec_public_key* self = (br_ec_public_key*)magic->mg_ptr;
405 4           ec_key_destroy(self);
406 4           Safefree(self);
407 4           return 0;
408             }
409              
410             static const MGVTBL Crypt__Bear__EC__PublicKey_magic = {
411             .svt_dup = ec_key_dup,
412             .svt_free = ec_key_free,
413             };
414              
415 0           static void S_ec_private_key_copy(pTHX_ br_ec_private_key* dest, const br_ec_private_key* source) {
416 0           dest->curve = source->curve;
417 0           dest->x = saveupvn(source->x, source->xlen);
418 0           dest->xlen = source->xlen;
419 0           }
420             #define ec_private_key_copy(dest, source) S_ec_private_key_copy(aTHX_ dest, source)
421             #define ec_private_key_destroy(target) Safefree((target)->x)
422              
423 0           static int ec_privatekey_dup(pTHX_ MAGIC* magic, CLONE_PARAMS* params) {
424 0           br_ec_private_key* old = (br_ec_private_key*)magic->mg_ptr;
425 0           br_ec_private_key* self = safemalloc(sizeof(br_ec_private_key));
426 0           ec_private_key_copy(self, old);
427 0           magic->mg_ptr = (char*)self;
428 0           return 0;
429             }
430              
431 2           static int ec_privatekey_free(pTHX_ SV* sv, MAGIC* magic) {
432 2           br_ec_private_key* self = (br_ec_private_key*)magic->mg_ptr;
433 2           ec_private_key_destroy(self);
434 2           Safefree(self);
435 2           return 0;
436             }
437              
438             static const MGVTBL Crypt__Bear__EC__PrivateKey_magic = {
439             .svt_dup = ec_privatekey_dup,
440             .svt_free = ec_privatekey_free,
441             };
442              
443             static const br_ec_impl* ec_default;
444             static const br_ec_impl* ec_c25519;
445             static br_ecdsa_sign ec_sign_default;
446             static br_ecdsa_vrfy ec_verify_default;
447              
448             typedef br_ec_public_key* Crypt__Bear__EC__PublicKey;
449             typedef br_ec_private_key* Crypt__Bear__EC__PrivateKey;
450             typedef const br_ec_impl* Crypt__Bear__EC;
451              
452              
453             /* PEM stuff */
454              
455             #define pem_flag_entry_for(name, value) make_map_int_entry(name, BR_PEM_ ## value)
456             static const map pem_flags = {
457             pem_flag_entry_for("line64", LINE64),
458             pem_flag_entry_for("crlf", CRLF),
459             };
460             #define lookup_pem_flag(name) (map_get(pem_flags, name, "pem flag").integer)
461              
462             typedef struct {
463             #ifdef MULTIPLICITY
464             tTHX aTHX;
465             #endif
466             br_pem_decoder_context decoder;
467             SV* callback;
468             SV* name;
469             SV* buffer;
470             } pem_decoder;
471              
472 718           static void pem_callback(void* ptr, const void* data, size_t length) {
473 718           pem_decoder* current = ptr;
474             dTHXa(current->aTHX);
475 718           sv_catpvn(current->buffer, data, length);
476 718           }
477              
478 0           static int pem_decoder_dup(pTHX_ MAGIC* magic, CLONE_PARAMS* params) {
479 0           pem_decoder* decoder = (pem_decoder*)magic->mg_ptr;
480 0           pem_decoder* self = safecalloc(1, sizeof(pem_decoder));
481              
482             #ifdef MULTIPLICITY
483             self->aTHX = aTHX;
484             self->callback = sv_dup_inc(decoder->callback, params);
485             if (decoder->buffer)
486             self->buffer = sv_dup_inc(decoder->buffer, params);
487             if (decoder->name)
488             self->name = sv_dup_inc(decoder->name, params);
489             if (decoder->decoder.dest_ctx)
490             self->decoder.dest_ctx = self;
491             #endif
492              
493 0           return 0;
494             }
495              
496 2           static int pem_decoder_free(pTHX_ SV* sv, MAGIC* magic) {
497 2           pem_decoder* decoder = (pem_decoder*)magic->mg_ptr;
498              
499 2           SvREFCNT_dec(decoder->callback);
500 2 50         if (decoder->buffer)
501 0           SvREFCNT_dec(decoder->buffer);
502 2 50         if (decoder->name)
503 0           SvREFCNT_dec(decoder->name);
504              
505 2           Safefree(decoder);
506              
507 2           return 0;
508             }
509              
510             static const MGVTBL Crypt__Bear__PEM__Decoder_magic = {
511             .svt_dup = pem_decoder_dup,
512             .svt_free = pem_decoder_free,
513             };
514              
515             typedef pem_decoder* Crypt__Bear__PEM__Decoder;
516              
517              
518             /* X509 stuff */
519              
520             #define usage_entry_for(name, value) make_map_int_entry(name, value)
521             static const map usages = {
522             usage_entry_for("key-exchange", BR_KEYTYPE_KEYX),
523             usage_entry_for("signing", BR_KEYTYPE_SIGN),
524             usage_entry_for("both", BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN),
525             };
526             typedef unsigned usage_type;
527              
528 149           static void S_dn_init(pTHX_ br_x500_name* dest, const unsigned char* data, size_t data_len) {
529 149           dest->data = saveupvn(data, data_len);
530 149           dest->len = data_len;
531 149           }
532             #define dn_init(dest, data, data_len) S_dn_init(aTHX_ dest, data, data_len)
533              
534 149           static void S_dn_copy(pTHX_ br_x500_name* dest, const br_x500_name* source) {
535 149           dn_init(dest, source->data, source->len);
536 149           }
537             #define dn_copy(dest, source) S_dn_copy(aTHX_ dest, source)
538              
539             #define dn_to_sv(dn) newSVpvn((const char*)(dn).data, (dn).len)
540              
541             #define dn_destroy(target) Safefree((target)->data)
542              
543             typedef struct certificate {
544             br_x509_certificate cert;
545             br_x509_decoder_context decoder;
546             br_x500_name dn;
547             } *Crypt__Bear__X509__Certificate;
548              
549             #define key_type_entry(name, value) make_map_int_entry(name, BR_KEYTYPE_ ## value)
550             static const map key_kinds = {
551             key_type_entry("rsa", RSA),
552             key_type_entry("ec", EC),
553             };
554             typedef unsigned key_kind_type;
555              
556             struct decoder_helper {
557             #ifdef MULTIPLICITY
558             tTHX aTHX;
559             #endif
560             SV* value;
561             };
562              
563 480           static void dn_decoder(void *ctx, const void *buf, size_t len) {
564 480           struct decoder_helper* current = (struct decoder_helper*) ctx;
565             dTHXa(current->aTHX);
566 480           sv_catpvn(current->value, buf, len);
567 480           }
568              
569 157           static void S_br_x509_certificate_init(pTHX_ br_x509_certificate* dest, const unsigned char* data, size_t data_len) {
570 157           dest->data = saveupvn(data, data_len);
571 157           dest->data_len = data_len;
572 157           }
573             #define br_x509_certificate_init(cert, data, data_len) S_br_x509_certificate_init(aTHX_ cert, data, data_len)
574              
575 5           static void S_br_x509_certificate_copy(pTHX_ br_x509_certificate* dest, const br_x509_certificate* source) {
576 5           br_x509_certificate_init(dest, source->data, source->data_len);
577 5           }
578             #define br_x509_certificate_copy(dest, source) S_br_x509_certificate_copy(aTHX_ dest, source)
579              
580             #define br_x509_certificate_destroy(target) Safefree((target)->data)
581              
582             #define br_x509_certificate_dn(self) dn_to_sv((self)->dn)
583             #define br_x509_certificate_is_ca(self) br_x509_decoder_isCA(&(self)->decoder)
584             #define br_x509_certificate_signer_key_type(self) br_x509_decoder_get_signer_key_type(&(self)->decoder)
585              
586 152           static void S_certificate_destroy(pTHX_ struct certificate* cert) {
587 152           dn_destroy(&cert->dn);
588 152           br_x509_certificate_destroy(&cert->cert);
589 152           }
590             #define certificate_destroy(target) S_certificate_destroy(aTHX_ target)
591              
592 0           static void S_certificate_copy(pTHX_ struct certificate* dest, const struct certificate* source) {
593 0           br_x509_certificate_copy(&dest->cert, &source->cert);
594 0           memcpy(&dest->decoder, &source->decoder, sizeof(br_x509_decoder_context));
595 0           dn_copy(&dest->dn, &source->dn);
596 0           }
597             #define certificate_copy(dest, source) S_certificate_copy(aTHX_ dest, source)
598              
599 0           static int certificate_dup(pTHX_ MAGIC* magic, CLONE_PARAMS* params) {
600 0           struct certificate* old = (struct certificate*)magic->mg_ptr;
601 0           struct certificate* self = safemalloc(sizeof(struct certificate));
602 0           certificate_copy(self, old);
603 0           magic->mg_ptr = (char*)self;
604 0           return 0;
605             }
606              
607 152           static int certificate_free(pTHX_ SV* sv, MAGIC* magic) {
608 152           struct certificate* cert = (struct certificate*)magic->mg_ptr;
609 152           certificate_destroy(cert);
610 152           Safefree(cert);
611 152           return 0;
612             }
613              
614             static const MGVTBL Crypt__Bear__X509__Certificate_magic = {
615             .svt_dup = certificate_dup,
616             .svt_free = certificate_free
617             };
618              
619 4           static SV* S_x509_key_unpack(pTHX_ const br_x509_pkey* public_key) {
620 4 100         if (public_key->key_type == BR_KEYTYPE_RSA) {
621 2           br_rsa_public_key* key = safemalloc(sizeof *key);
622 2           rsa_key_copy(key, &public_key->key.rsa);
623 2           return make_magic(key, "Crypt::Bear::RSA::PublicKey", &Crypt__Bear__RSA__PublicKey_magic);
624 2 50         } else if (public_key->key_type == BR_KEYTYPE_EC) {
625 2           br_ec_public_key* key = safemalloc(sizeof *key);
626 2           ec_key_copy(key, &public_key->key.ec);
627 2           return make_magic(key, "Crypt::Bear::EC::PublicKey", &Crypt__Bear__EC__PublicKey_magic);
628             }
629 0           return &PL_sv_undef;
630             }
631             #define x509_key_unpack(key) S_x509_key_unpack(aTHX_ key)
632              
633              
634 149           static void S_x509_key_copy(pTHX_ br_x509_pkey* dest, const br_x509_pkey* source) {
635 149           dest->key_type = source->key_type;
636 149 100         if (source->key_type == BR_KEYTYPE_RSA) {
637 104           rsa_key_copy(&dest->key.rsa, &source->key.rsa);
638 45 50         } else if (source->key_type == BR_KEYTYPE_EC) {
639 45           ec_key_copy(&dest->key.ec, &source->key.ec);
640             }
641 149           }
642             #define x509_key_copy(dest, source) S_x509_key_copy(aTHX_ dest, source)
643              
644 149           static void S_x509_key_destroy(pTHX_ br_x509_pkey* target) {
645 149 100         if (target->key_type == BR_KEYTYPE_RSA) {
646 104           rsa_key_destroy(&target->key.rsa);
647 45 50         } else if (target->key_type == BR_KEYTYPE_EC) {
648 45           ec_key_destroy(&target->key.ec);
649             }
650 149           }
651             #define x509_key_destroy(dest) S_x509_key_destroy(aTHX_ dest)
652              
653              
654 1           static void S_trust_anchor_copy(pTHX_ br_x509_trust_anchor* dest, const br_x509_trust_anchor* source) {
655 1           dest->flags = source->flags;
656 1           dn_copy(&dest->dn, &source->dn);
657 1           x509_key_copy(&dest->pkey, &source->pkey);
658 1           }
659             #define trust_anchor_copy(dest, source) S_trust_anchor_copy(aTHX_ dest, source)
660              
661 149           static void S_trust_anchor_destroy(pTHX_ br_x509_trust_anchor* target) {
662 149           Safefree(target->dn.data);
663 149           x509_key_destroy(&target->pkey);
664 149           }
665             #define trust_anchor_destroy(target) S_trust_anchor_destroy(aTHX_ target)
666              
667             typedef struct trust_anchors {
668             br_x509_trust_anchor* array;
669             size_t allocated;
670             size_t used;
671             } *Crypt__Bear__X509__TrustAnchors;
672              
673              
674 4           static void trust_anchors_init(struct trust_anchors* target) {
675 4           target->array = NULL;
676 4           target->allocated = 0;
677 4           target->used = 0;
678 4           }
679              
680 5           static void S_trust_anchors_destroy(pTHX_ struct trust_anchors* target) {
681 154 100         for (size_t i = 0; i < target->used; i++) {
682 149           trust_anchor_destroy(target->array + i);
683             }
684 5           Safefree(target->array);
685 5           }
686             #define trust_anchors_destroy(target) S_trust_anchors_destroy(aTHX_ target)
687              
688 1           static void S_trust_anchors_copy(pTHX_ struct trust_anchors* dest, const struct trust_anchors* source) {
689 1           dest->used = source->used;
690 1           dest->array = safecalloc(source->allocated, sizeof(br_x509_trust_anchor));
691 1           dest->allocated = source->allocated;
692              
693 2 100         for (size_t i = 0; i < source->used; i++) {
694 1           trust_anchor_copy(dest->array + i, source->array + i);
695             }
696 1           }
697             #define trust_anchors_copy(dest, source) S_trust_anchors_copy(aTHX_ dest, source)
698              
699 148           static void S_trust_anchors_push(pTHX_ struct trust_anchors* anchors, const br_x509_trust_anchor* anchor) {
700 148 100         if (anchors->allocated == 0) {
701 4           anchors->array = safemalloc(8 * sizeof(br_x509_trust_anchor));
702 4           anchors->allocated = 8;
703             }
704 144 100         else if (anchors->used == anchors->allocated) {
705 5 50         anchors->allocated = anchors->allocated ? 2 * anchors->allocated : 4;
706 5           size_t new_size = anchors->allocated * sizeof(br_x509_trust_anchor);
707 5           anchors->array = saferealloc(anchors->array, new_size);
708             }
709 148           memcpy(anchors->array + anchors->used, anchor, sizeof *anchor);
710 148           anchors->used++;
711 148           }
712             #define trust_anchors_push(anchors, new_anchor) S_trust_anchors_push(aTHX_ anchors, new_anchor)
713              
714 0           static int trust_anchors_dup(pTHX_ MAGIC* magic, CLONE_PARAMS* params) {
715 0           struct trust_anchors* old = (struct trust_anchors*)magic->mg_ptr;
716 0           struct trust_anchors* copy = safemalloc(sizeof *copy);
717 0           trust_anchors_copy(copy, old);
718 0           return 0;
719             }
720              
721 4           static int trust_anchors_free(pTHX_ SV* sv, MAGIC* magic) {
722 4           struct trust_anchors* trust = (struct trust_anchors*)magic->mg_ptr;
723 4           trust_anchors_destroy(trust);
724 4           Safefree(trust);
725 4           return 0;
726             }
727              
728             static const MGVTBL Crypt__Bear__X509__TrustAnchors_magic = {
729             .svt_dup = trust_anchors_dup,
730             .svt_free = trust_anchors_free,
731             };
732              
733              
734             typedef struct certificate_chain {
735             br_x509_certificate* array;
736             size_t allocated;
737             size_t used;
738             unsigned signer_key_type;
739             } *Crypt__Bear__X509__Certificate__Chain;
740              
741              
742 2           static void certificate_chain_init(struct certificate_chain* target) {
743 2           target->array = NULL;
744 2           target->allocated = 0;
745 2           target->used = 0;
746 2           }
747              
748 2           static void S_certificate_chain_push(pTHX_ struct certificate_chain* certificates, const br_x509_certificate* anchor) {
749 2 50         if (certificates->used == certificates->allocated) {
750 2 50         certificates->allocated = certificates->allocated ? 2 * certificates->allocated : 4;
751 2           size_t new_size = certificates->allocated * sizeof(br_x509_certificate);
752 2           certificates->array = saferealloc(certificates->array, new_size);
753             }
754 2           memcpy(certificates->array + certificates->used, anchor, sizeof *anchor);
755 2           certificates->used++;
756 2           }
757             #define certificate_chain_push(anchors, new_anchor) S_certificate_chain_push(aTHX_ anchors, new_anchor)
758              
759 3           static void S_certificate_chain_copy(pTHX_ struct certificate_chain* dest, const struct certificate_chain* source) {
760 3           dest->used = source->used;
761 3           dest->array = safecalloc(source->allocated, sizeof(br_x509_certificate));
762 3           dest->allocated = source->allocated;
763              
764 6 100         for (size_t i = 0; i < source->used; i++) {
765 3           br_x509_certificate_copy(dest->array + i, source->array + i);
766             }
767 3           }
768             #define certificate_chain_copy(dest, source) S_certificate_chain_copy(aTHX_ dest, source)
769              
770 0           static int certificate_chain_dup(pTHX_ MAGIC* magic, CLONE_PARAMS* params) {
771 0           struct certificate_chain* old = (struct certificate_chain*)magic->mg_ptr;
772 0           struct certificate_chain* copy = safemalloc(sizeof *copy);
773 0           certificate_chain_copy(copy, old);
774 0           return 0;
775             }
776              
777 6           static void S_certificate_chain_destroy(pTHX_ struct certificate_chain* chain) {
778 11 100         for (size_t i = 0; i < chain->used; i++) {
779 5           br_x509_certificate_destroy(chain->array + i);
780             }
781 6           Safefree(chain->array);
782 6           }
783             #define certificate_chain_destroy(chain) S_certificate_chain_destroy(aTHX_ chain)
784              
785 3           static int certificate_chain_free(pTHX_ SV* sv, MAGIC* magic) {
786 3           struct certificate_chain* chain = (struct certificate_chain*)magic->mg_ptr;
787 3           certificate_chain_destroy(chain);
788 3           Safefree(chain);
789 3           return 0;
790             }
791              
792             static const MGVTBL Crypt__Bear__X509__Certificate__Chain_magic = {
793             .svt_dup = certificate_chain_dup,
794             .svt_free = certificate_chain_free,
795             };
796              
797             typedef struct private_key {
798             unsigned key_type;
799             union {
800             br_rsa_private_key rsa;
801             br_ec_private_key ec;
802             };
803             } *Crypt__Bear__X509__PrivateKey;
804              
805 2           static void S_private_key_copy(pTHX_ struct private_key* copy, const struct private_key* old) {
806 2           copy->key_type = old->key_type;
807 2 50         if (old->key_type == BR_KEYTYPE_RSA)
808 2           rsa_private_key_copy(©->rsa, &old->rsa);
809             else
810 0           ec_private_key_copy(©->ec, &old->ec);
811 2           }
812             #define private_key_copy(copy, old) S_private_key_copy(aTHX_ copy, old)
813              
814 0           static int private_key_dup(pTHX_ MAGIC* magic, CLONE_PARAMS* params) {
815 0           struct private_key* old = (struct private_key*)magic->mg_ptr;
816 0           struct private_key* copy = safemalloc(sizeof *copy);
817 0           private_key_copy(copy, old);
818 0           return 0;
819             }
820              
821 5           static void S_private_key_destroy(pTHX_ struct private_key* self) {
822 5 100         if (self->key_type == BR_KEYTYPE_RSA)
823 4           rsa_private_key_destroy(&self->rsa);
824             else
825 1           ec_private_key_destroy(&self->ec);
826 5           }
827             #define private_key_destroy(self) S_private_key_destroy(aTHX_ self)
828              
829 2           static int private_key_free(pTHX_ SV* sv, MAGIC* magic) {
830 2           struct private_key* self = (struct private_key*)magic->mg_ptr;
831 2           private_key_destroy(self);
832 2           return 0;
833             }
834              
835             static const MGVTBL Crypt__Bear__X509__PrivateKey_magic = {
836             .svt_dup = private_key_dup,
837             .svt_free = private_key_free,
838             };
839              
840 1           static unsigned S_private_key_usage(pTHX_ struct private_key* key) {
841 1 50         if (key->key_type == BR_KEYTYPE_EC) {
842 0           unsigned result = BR_KEYTYPE_KEYX;
843             if (key->ec.curve == BR_EC_secp256r1 || key->ec.curve == BR_EC_secp384r1 || BR_EC_secp521r1)
844 0           result |= BR_KEYTYPE_SIGN;
845 0           return result;
846             } else {
847 1           return BR_KEYTYPE_SIGN;
848             }
849             }
850             #define private_key_usage(key) S_private_key_usage(aTHX_ key)
851              
852             typedef const br_x509_class** Crypt__Bear__X509__Validator;
853              
854             typedef struct validator_minimal {
855             br_x509_minimal_context context;
856             struct trust_anchors anchors;
857             } *Crypt__Bear__X509__Validator__Minimal;
858              
859             typedef br_x509_knownkey_context* Crypt__Bear__X509__Validator__KnownKey;
860              
861             /* SSL stuff */
862              
863             #define ssl_flag_entry(name, key) make_map_int_entry(name, BR_OPT_ ## key)
864             static const map ssl_flags = {
865             ssl_flag_entry("enforce-server-preferences", ENFORCE_SERVER_PREFERENCES),
866             ssl_flag_entry("no-renegotiation", NO_RENEGOTIATION),
867             ssl_flag_entry("tolerate-no-client-auth", TOLERATE_NO_CLIENT_AUTH),
868             ssl_flag_entry("fail-on-alpn-mismatch", FAIL_ON_ALPN_MISMATCH),
869             };
870             typedef unsigned ssl_flag_type;
871              
872             #define ssl_version_entry(name, key) make_map_int_entry(name, BR_ ## key)
873             static const map ssl_versions = {
874             ssl_version_entry("tls-1.0", TLS10),
875             ssl_version_entry("tls-1.1", TLS11),
876             ssl_version_entry("tls-1.2", TLS12),
877             };
878             typedef unsigned ssl_version_type;
879              
880             typedef br_ssl_session_parameters* Crypt__Bear__SSL__Session;
881             typedef br_ssl_engine_context* Crypt__Bear__SSL__Engine;
882              
883             typedef const br_ssl_client_certificate_class** Crypt__Bear__SSL__Client__Certificate;
884              
885              
886             typedef struct private_certificate {
887             struct certificate_chain chain;
888             struct private_key key;
889             unsigned usage;
890             } *Crypt__Bear__SSL__PrivateCertificate;
891              
892             #define private_certificate_init(self) memset(self, '\0', sizeof(struct private_certificate))
893              
894 1           static void S_private_certificate_copy(pTHX_ struct private_certificate* dest, const struct private_certificate* source) {
895 1           certificate_chain_copy(&dest->chain, &source->chain);
896 1           private_key_copy(&dest->key, &source->key);
897 1           }
898             #define private_certificate_copy(dest, source) S_private_certificate_copy(aTHX_ dest, source)
899              
900 0           static int private_certificate_dup(pTHX_ MAGIC* magic, CLONE_PARAMS* params) {
901 0           struct private_certificate* old = (struct private_certificate*)magic->mg_ptr;
902 0           struct private_certificate* copy = safemalloc(sizeof *copy);
903              
904 0           private_certificate_copy(copy, old);
905 0           magic->mg_ptr = (char*)copy;
906              
907 0           return 0;
908             }
909              
910 3           static void S_private_certificate_destroy(pTHX_ struct private_certificate* self) {
911 3           private_key_destroy(&self->key);
912 3           certificate_chain_destroy(&self->chain);
913 3           }
914             #define private_certificate_destroy(self) S_private_certificate_destroy(aTHX_ self)
915              
916 1           static int private_certificate_free(pTHX_ SV* sv, MAGIC* magic) {
917 1           struct private_certificate* self = (struct private_certificate*)magic->mg_ptr;
918 1           private_certificate_destroy(self);
919 1           Safefree(self);
920 1           return 0;
921             }
922              
923              
924             static const MGVTBL Crypt__Bear__SSL__PrivateCertificate_magic = {
925             .svt_dup = private_certificate_dup,
926             .svt_free = private_certificate_free,
927             };
928              
929              
930             typedef struct ssl_client {
931             br_ssl_client_context context;
932             struct private_certificate private;
933             unsigned char buffer[BR_SSL_BUFSIZE_BIDI];
934             br_x509_minimal_context minimal;
935             struct trust_anchors trust_anchors;
936             } *Crypt__Bear__SSL__Client;
937              
938 0           static void ssl_engine_buffer_move(br_ssl_engine_context* new, const br_ssl_engine_context* old, unsigned char* buffer) {
939             // HIC SUNT DRACONES
940 0           new->ibuf = buffer;
941 0           new->obuf = buffer + old->ibuf_len;
942 0           }
943              
944 0           static int ssl_client_dup(pTHX_ MAGIC* magic, CLONE_PARAMS* params) {
945 0           struct ssl_client* old = (struct ssl_client*)magic->mg_ptr;
946 0           struct ssl_client* copy = safemalloc(sizeof *copy);
947              
948 0           private_certificate_copy(©->private, &old->private);
949 0           trust_anchors_copy(©->trust_anchors, &old->trust_anchors);
950 0           br_x509_minimal_init_full(©->minimal, copy->trust_anchors.array, copy->trust_anchors.used);
951 0           br_ssl_engine_set_x509(©->context.eng, ©->minimal.vtable);
952 0           ssl_engine_buffer_move(©->context.eng, &old->context.eng, copy->buffer);
953              
954 0           magic->mg_ptr = (char*)copy;
955              
956 0           return 0;
957             }
958              
959 1           static int ssl_client_free(pTHX_ SV* sv, MAGIC* magic) {
960 1           struct ssl_client* self = (struct ssl_client*)magic->mg_ptr;
961              
962 1           trust_anchors_destroy(&self->trust_anchors);
963 1           private_certificate_destroy(&self->private);
964              
965 1           Safefree(self);
966              
967 1           return 0;
968             }
969              
970             static const MGVTBL Crypt__Bear__SSL__Client_magic = {
971             .svt_dup = ssl_client_dup,
972             .svt_free = ssl_client_free,
973             };
974              
975             typedef struct ssl_server {
976             br_ssl_server_context context;
977             struct private_certificate private;
978             unsigned char buffer[BR_SSL_BUFSIZE_BIDI];
979             } *Crypt__Bear__SSL__Server;
980              
981              
982 0           static int ssl_server_dup(pTHX_ MAGIC* magic, CLONE_PARAMS* params) {
983 0           struct ssl_server* old = (struct ssl_server*)magic->mg_ptr;
984 0           struct ssl_server* copy = safemalloc(sizeof *copy);
985              
986 0           private_certificate_copy(©->private, &old->private);
987 0           ssl_engine_buffer_move(©->context.eng, &old->context.eng, copy->buffer);
988              
989 0           magic->mg_ptr = (char*)copy;
990              
991 0           return 0;
992             }
993              
994 1           static int ssl_server_free(pTHX_ SV* sv, MAGIC* magic) {
995 1           struct ssl_server* self = (struct ssl_server*)magic->mg_ptr;
996 1           private_certificate_destroy(&self->private);
997 1           Safefree(self);
998 1           return 0;
999             }
1000              
1001             static const MGVTBL Crypt__Bear__SSL__Server_magic = {
1002             .svt_dup = ssl_server_dup,
1003             .svt_free = ssl_server_free,
1004             };
1005              
1006              
1007             /* DIRTY STUFF */
1008              
1009             // Make various default values pretty for XS's error messages
1010             #define automatic private_key_usage(key)
1011             #define undef &PL_sv_undef
1012              
1013             // Unicode stuff. This will force byte semantics on all string
1014             #undef SvPV
1015             #define SvPV(sv, len) SvPVbyte(sv, len)
1016             #undef SvPV_nolen
1017             #define SvPV_nolen(sv) SvPVbyte_nolen(sv)
1018              
1019              
1020             MODULE = Crypt::Bear PACKAGE = Crypt::Bear PREFIX = br_
1021              
1022             PROTOTYPES: DISABLE
1023              
1024             SV* br_get_config(class)
1025             CODE:
1026 1           const br_config_option* current = br_get_config();
1027 1           HV* hash = newHV();
1028 42 100         while (current->name) {
1029 41           SV* val = newSVuv(current->value);
1030 41           hv_store(hash, current->name, strlen(current->name), val, 0);
1031 41           current++;
1032             }
1033 1           RETVAL = newRV_noinc((SV*)hash);
1034             OUTPUT:
1035             RETVAL
1036              
1037              
1038             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::Hash PREFIX = br_hash_
1039              
1040             Crypt::Bear::Hash br_hash_new(class, hash_type hash)
1041             CODE:
1042 5           RETVAL = safemalloc(sizeof *RETVAL);
1043 5           (*hash->init)(&RETVAL->vtable);
1044             OUTPUT:
1045             RETVAL
1046              
1047             void br_hash_update(Crypt::Bear::Hash self, const char* data, size_t length(data))
1048              
1049             SV* br_hash_out(Crypt::Bear::Hash self)
1050             CODE:
1051 5           RETVAL = make_buffer(br_hash_output_size(self));
1052 5           (self->vtable->out)(&self->vtable, SvPVX(RETVAL));
1053             OUTPUT:
1054             RETVAL
1055              
1056             SV* br_hash_state(Crypt::Bear::Hash self)
1057             CODE:
1058 0           RETVAL = make_buffer(br_hash_state_size(self));
1059 0           (self->vtable->state)(&self->vtable, SvPVX(RETVAL));
1060             OUTPUT:
1061             RETVAL
1062              
1063             void br_hash_set_state(Crypt::Bear::Hash self, const char* state, size_t length(state))
1064             CODE:
1065 0           size_t output_size = br_hash_state_size(self);
1066 0 0         if (STRLEN_length_of_state != br_hash_state_size(self))
1067 0           Perl_croak(aTHX_ "State hash wrong size");
1068 0           (self->vtable->set_state)(&self->vtable, state, STRLEN_length_of_state);
1069              
1070             hash_type br_hash_digest(Crypt::Bear::Hash self)
1071              
1072             UV br_hash_output_size(Crypt::Bear::Hash self)
1073              
1074              
1075             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::HMAC::Key PREFIX = br_hmac_key_
1076              
1077             Crypt::Bear::HMAC::Key br_hmac_key_new(class, hash_type hash, const char* key, size_t length(key))
1078             CODE:
1079 10           RETVAL = safemalloc(sizeof *RETVAL);
1080 10           br_hmac_key_init(RETVAL, hash, key, STRLEN_length_of_key);
1081             OUTPUT:
1082             RETVAL
1083              
1084             hash_type br_hmac_key_digest(Crypt::Bear::HMAC::Key self)
1085              
1086             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::HMAC PREFIX = br_hmac_
1087              
1088             Crypt::Bear::HMAC br_hmac_new(class, Crypt::Bear::HMAC::Key key, size_t out_length = 0)
1089             CODE:
1090 10           RETVAL = safemalloc(sizeof *RETVAL);
1091 10           br_hmac_init(RETVAL, key, out_length);
1092             OUTPUT:
1093             RETVAL
1094              
1095             IV br_hmac_size(Crypt::Bear::HMAC self)
1096              
1097             void br_hmac_update(Crypt::Bear::HMAC self, const char* data, size_t length(data))
1098              
1099             SV* br_hmac_out(Crypt::Bear::HMAC self)
1100             CODE:
1101 10           RETVAL = make_buffer(br_hmac_size(self));
1102 10           br_hmac_out(self, SvPVX(RETVAL));
1103             OUTPUT:
1104             RETVAL
1105              
1106             hash_type br_hmac_digest(Crypt::Bear::HMAC self)
1107              
1108              
1109             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::HKDF PREFIX = br_hkdf_
1110              
1111             Crypt::Bear::HKDF br_hkdf_new(class, hash_type hash, const char* salt, size_t length(salt))
1112             CODE:
1113 0           RETVAL = safemalloc(sizeof *RETVAL);
1114 0           br_hkdf_init(RETVAL, hash, salt, STRLEN_length_of_salt);
1115             OUTPUT:
1116             RETVAL
1117              
1118             void br_hkdf_inject(Crypt::Bear::HKDF self, const char* data, size_t length(data))
1119              
1120             void br_hkdf_flip(Crypt::Bear::HKDF self)
1121              
1122             SV* br_hkdf_produce(Crypt::Bear::HKDF self, size_t output_size, const char* info, size_t length(info))
1123             CODE:
1124 0           RETVAL = make_buffer(output_size);
1125 0           br_hkdf_produce(self, info, STRLEN_length_of_info, SvPV_nolen(RETVAL), output_size);
1126             OUTPUT:
1127             RETVAL
1128              
1129              
1130             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::Shake PREFIX = br_shake_
1131              
1132             #if 0
1133             Crypt::Bear::Shake br_shake_new(class, hash_type hash, UV security_level)
1134             CODE:
1135             OUTPUT:
1136             RETVAL
1137              
1138             void br_shake_inject(Crypt::Bear::Shake self, const char* data, size_t length(data))
1139              
1140             void br_shake_flip(Crypt::Bear::Shake self)
1141              
1142             SV* br_shake_produce(Crypt::Bear::Shake self, const char* info, size_t length(info))
1143             CODE:
1144             RETVAL = make_buffer(output_size);
1145             br_shake_produce(self, info, STRLEN_length_of_info, SvPV_nolen(RETVAL), output_size);
1146             OUTPUT:
1147             RETVAL
1148              
1149             #endif
1150              
1151              
1152             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::CBC::Enc PREFIX = br_block_cbcenc_
1153              
1154             IV br_block_cbcenc_block_size(Crypt::Bear::CBC::Enc self)
1155              
1156             SV* br_block_cbcenc_run(Crypt::Bear::CBC::Enc self, const char* iv, STRLEN length(iv), const char* data, size_t length(data))
1157             CODE:
1158 11 50         if ((STRLEN_length_of_data % br_block_cbcenc_block_size(self)) != 0)
1159 0           Perl_croak(aTHX_ "Data size should be a multiple of %u bytes", br_block_cbcenc_block_size(self));
1160 11 50         if (STRLEN_length_of_iv != br_block_cbcenc_block_size(self))
1161 0           Perl_croak(aTHX_ "IV should be %u bytes", br_block_cbcenc_block_size(self));
1162              
1163 11           char iv_copy[STRLEN_length_of_iv];
1164 11           memcpy(iv_copy, iv, STRLEN_length_of_iv);
1165 11           RETVAL = newSVpvn(data, STRLEN_length_of_data);
1166 11           ((*self)->run)(self, iv_copy, SvPV_nolen(RETVAL), STRLEN_length_of_data);
1167             OUTPUT:
1168             RETVAL
1169              
1170              
1171             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::CBC::Dec PREFIX = br_block_cbcdec_
1172              
1173             IV br_block_cbcdec_block_size(Crypt::Bear::CBC::Dec self)
1174              
1175             SV* br_block_cbcdec_run(Crypt::Bear::CBC::Dec self, const char* iv, STRLEN length(iv), const char* data, size_t length(data))
1176             CODE:
1177 11 50         if ((STRLEN_length_of_data % br_block_cbcdec_block_size(self)) != 0)
1178 0           Perl_croak(aTHX_ "data size should be a multiple of %u bytes", br_block_cbcdec_block_size(self));
1179 11 50         if (STRLEN_length_of_iv != br_block_cbcdec_block_size(self))
1180 0           Perl_croak(aTHX_ "IV should be %u bytes", br_block_cbcdec_block_size(self));
1181              
1182 11           char iv_copy[STRLEN_length_of_iv];
1183 11           memcpy(iv_copy, iv, STRLEN_length_of_iv);
1184 11           RETVAL = newSVpvn(data, STRLEN_length_of_data);
1185 11           ((*self)->run)(self, iv_copy, SvPV_nolen(RETVAL), STRLEN_length_of_data);
1186             OUTPUT:
1187             RETVAL
1188              
1189              
1190             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::CTR PREFIX = br_block_ctr_
1191              
1192             IV br_block_ctr_block_size(Crypt::Bear::CTR self)
1193              
1194             SV* br_block_ctr_run(Crypt::Bear::CTR self, const char* iv, STRLEN length(iv), U32 counter, const char* data, size_t length(data))
1195             CODE:
1196 22 50         if ((STRLEN_length_of_data % br_block_ctr_block_size(self)) != 0)
1197 0           Perl_croak(aTHX_ "data size should be a multiple of %u bytes", br_block_ctr_block_size(self));
1198 22 50         if (STRLEN_length_of_iv != br_block_ctr_block_size(self))
1199 0           Perl_croak(aTHX_ "IV should be %u bytes", br_block_ctr_block_size(self));
1200              
1201 22           char iv_copy[STRLEN_length_of_iv];
1202 22           memcpy(iv_copy, iv, STRLEN_length_of_iv);
1203 22           RETVAL = newSVpvn(data, STRLEN_length_of_data);
1204 22           ((*self)->run)(self, iv_copy, counter, SvPV_nolen(RETVAL), STRLEN_length_of_data);
1205             OUTPUT:
1206             RETVAL
1207              
1208              
1209             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::AES_CBC::Enc PREFIX = br_block_aes_cbcenc_
1210             BOOT:
1211 50           push_isa(Crypt::Bear::AES_CBC::Enc, Crypt::Bear::CBC::Enc);
1212 50           aes_cbc_enc = br_aes_x86ni_cbcenc_get_vtable();
1213 50 50         if (!aes_cbc_enc)
1214 0           aes_cbc_enc = &br_aes_ct_cbcenc_vtable;
1215              
1216             Crypt::Bear::AES_CBC::Enc br_block_aes_cbcenc_new(class, const char* key, size_t length(key))
1217             CODE:
1218 11           RETVAL = safemalloc(aes_cbc_enc->context_size);
1219 11           (aes_cbc_enc->init)((const br_block_cbcenc_class**)RETVAL, key, STRLEN_length_of_key);
1220             OUTPUT:
1221             RETVAL
1222              
1223              
1224             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::AES_CBC::Dec PREFIX = br_block_aes_cbcdec_
1225             BOOT:
1226 50           push_isa(Crypt::Bear::AES_CBC::Dec, Crypt::Bear::CBC::Dec);
1227 50           aes_cbc_dec = br_aes_x86ni_cbcdec_get_vtable();
1228 50 50         if (!aes_cbc_dec)
1229             #if IVSIZE == 8
1230 0           aes_cbc_dec = &br_aes_ct64_cbcdec_vtable;
1231             #else
1232             aes_cbc_dec = &br_aes_ct_cbcdec_vtable;
1233             #endif
1234              
1235             Crypt::Bear::AES_CBC::Dec br_block_aes_cbcdec_new(class, const char* key, size_t length(key))
1236             CODE:
1237 11           RETVAL = safemalloc(aes_cbc_dec->context_size);
1238 11           (aes_cbc_dec->init)((const br_block_cbcdec_class**)RETVAL, key, STRLEN_length_of_key);
1239             OUTPUT:
1240             RETVAL
1241              
1242              
1243             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::AES_CTR PREFIX = br_block_aes_ctr_
1244             BOOT:
1245 50           push_isa(Crypt::Bear::AES_CTR, Crypt::Bear::CTR);
1246 50           aes_ctr = br_aes_x86ni_ctr_get_vtable();
1247 50 50         if (!aes_ctr)
1248             #if IVSIZE == 8
1249 0           aes_ctr = &br_aes_ct64_ctr_vtable;
1250             #else
1251             aes_ctr = &br_aes_ct_ctr_vtable;
1252             #endif
1253              
1254             Crypt::Bear::AES_CTR br_block_aes_ctr_new(class, const char* key, size_t length(key))
1255             CODE:
1256 19           RETVAL = safemalloc(aes_ctr->context_size);
1257 19           (aes_ctr->init)(&RETVAL->vtable, key, STRLEN_length_of_key);
1258             OUTPUT:
1259             RETVAL
1260              
1261             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::CTRCBC PREFIX = br_block_ctrcbc_
1262              
1263              
1264             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::AES_CTRCBC PREFIX = br_block_aes_ctrcbc_
1265             BOOT:
1266 50           push_isa(Crypt::Bear::AES_CTRCBC, Crypt::Bear::CTRCBC);
1267 50           aes_ctrcbc = br_aes_x86ni_ctrcbc_get_vtable();
1268 50 50         if (!aes_ctrcbc)
1269 0           aes_ctrcbc = &br_aes_ct_ctrcbc_vtable;
1270              
1271             Crypt::Bear::AES_CTRCBC br_block_aes_ctrcbc_new(class, const char* data, size_t length(data))
1272             CODE:
1273 0           RETVAL = safemalloc(aes_ctrcbc->context_size);
1274 0           (aes_ctrcbc->init)(&RETVAL->vtable, data, STRLEN_length_of_data);
1275             OUTPUT:
1276             RETVAL
1277              
1278             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::ChaCha20
1279              
1280              
1281              
1282             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::AEAD PREFIX = br_aead_
1283              
1284             void br_aead_reset(Crypt::Bear::AEAD self, const char* iv, size_t length(iv))
1285              
1286             void br_aead_aad_inject(Crypt::Bear::AEAD self, const char* iv, size_t length(iv))
1287              
1288             void br_aead_flip(Crypt::Bear::AEAD self)
1289              
1290             SV* run(Crypt::Bear::AEAD self, const char* data, size_t length(data), bool encrypt)
1291             CODE:
1292 16           RETVAL = newSVpvn(data, STRLEN_length_of_data);
1293 16           br_aead_run(self, encrypt, SvPV_nolen(RETVAL), STRLEN_length_of_data);
1294             OUTPUT:
1295             RETVAL
1296              
1297             SV* get_tag(Crypt::Bear::AEAD self)
1298             CODE:
1299 8           RETVAL = make_buffer((*self)->tag_size);
1300 8           br_aead_get_tag(self, SvPVX(RETVAL));
1301             OUTPUT:
1302             RETVAL
1303              
1304             bool check_tag(Crypt::Bear::AEAD self, const char* tag, size_t length(tag))
1305             CODE:
1306 8 50         if (STRLEN_length_of_tag != (*self)->tag_size)
1307 0           Perl_croak(aTHX_ "Incorrect tag size, got %zu expected %zu", STRLEN_length_of_tag, (*self)->tag_size);
1308 8 50         RETVAL = br_aead_check_tag(self, tag);
1309             OUTPUT:
1310             RETVAL
1311              
1312              
1313             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::GCM PREFIX = br_gcm_
1314             BOOT:
1315 50           push_isa(Crypt::Bear::GCM, Crypt::Bear::AEAD);
1316 50           ghash_impl = br_ghash_pclmul_get();
1317 50 50         if (!ghash_impl)
1318             #if IVSIZE == 8
1319 0           ghash_impl = &br_ghash_ctmul64;
1320             #else
1321             ghash_impl = &br_ghash_ctmul;
1322             #endif
1323              
1324              
1325             Crypt::Bear::GCM br_gcm_new(class, Crypt::Bear::CTR ctr)
1326             CODE:
1327 8           RETVAL = safemalloc(sizeof *RETVAL);
1328 8           br_gcm_init(RETVAL, ctr, ghash_impl);
1329             OUTPUT:
1330             RETVAL
1331              
1332              
1333             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::EAX PREFIX = br_eax_
1334             BOOT:
1335 50           push_isa(Crypt::Bear::EAX, Crypt::Bear::AEAD);
1336              
1337             Crypt::Bear::EAX br_eax_new(class, Crypt::Bear::CTRCBC ctrcbc)
1338             CODE:
1339 0           RETVAL = safemalloc(sizeof *RETVAL);
1340 0           br_eax_init(RETVAL, ctrcbc);
1341             OUTPUT:
1342             RETVAL
1343              
1344              
1345             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::CCM PREFIX = br_ccm_
1346             BOOT:
1347 50           push_isa(Crypt::Bear::CCM, Crypt::Bear::AEAD);
1348              
1349             Crypt::Bear::CCM br_ccm_new(class, Crypt::Bear::CTRCBC ctrcbc)
1350             CODE:
1351 0           RETVAL = safemalloc(sizeof *RETVAL);
1352 0           br_ccm_init(RETVAL, ctrcbc);
1353             OUTPUT:
1354             RETVAL
1355              
1356              
1357             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::PRNG PREFIX = br_prng_
1358             BOOT:
1359 50           system_seeder = br_prng_seeder_system(&system_seeder_name);
1360              
1361             const char* br_prng_system_seeder_name(class)
1362              
1363             SV* br_prng_generate(Crypt::Bear::PRNG self, size_t length)
1364             CODE:
1365 4           RETVAL = make_buffer(length);
1366 4           ((*self)->generate)(self, SvPVX(RETVAL), length);
1367             OUTPUT:
1368             RETVAL
1369              
1370             void br_prng_update(Crypt::Bear::PRNG self, const char* data, size_t length(data))
1371              
1372             bool br_prng_system_seed(Crypt::Bear::PRNG self)
1373             CODE:
1374 4 50         RETVAL = system_seeder ? system_seeder(self) : FALSE;
    50          
    50          
1375             OUTPUT:
1376             RETVAL
1377              
1378              
1379             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::HMAC::DRBG PREFIX = br_hmac_drbg_
1380             BOOT:
1381 50           push_isa(Crypt::Bear::HMAC::DRBG, Crypt::Bear::PRNG);
1382              
1383             Crypt::Bear::HMAC::DRBG br_hmac_drbg_new(class, hash_type hash, const char* seed, size_t length(seed))
1384             CODE:
1385 3           RETVAL = safemalloc(sizeof *RETVAL);
1386 3           br_hmac_drbg_init(RETVAL, hash, seed, STRLEN_length_of_seed);
1387             OUTPUT:
1388             RETVAL
1389              
1390             hash_type br_hmac_drbg_digest(Crypt::Bear::HMAC::DRBG self)
1391              
1392              
1393             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::AES_CTR::DRBG PREFIX = br_aesctr_drbg_
1394             BOOT:
1395 50           push_isa(Crypt::Bear::AES_CTR::DRBG, Crypt::Bear::PRNG);
1396              
1397              
1398             Crypt::Bear::AES_CTR::DRBG br_aesctr_drbg_new(class, const char* seed, size_t length(seed))
1399             CODE:
1400 1           RETVAL = safemalloc(sizeof *RETVAL);
1401 1           br_aesctr_drbg_init(RETVAL, aes_ctr, seed, STRLEN_length_of_seed);
1402             OUTPUT:
1403             RETVAL
1404              
1405              
1406             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::RSA PREFIX = br_rsa_
1407             BOOT:
1408 50           br_rsa_generate_keypair = br_rsa_keygen_get_default();
1409              
1410             NO_OUTPUT bool br_rsa_generate_keypair(Crypt::Bear::PRNG prng, OUTLIST Crypt::Bear::RSA::PublicKey key, OUTLIST Crypt::Bear::RSA::PrivateKey private_key, size_t size, UV exponent = 0)
1411             INIT:
1412 1           key = safemalloc(sizeof(br_rsa_public_key));
1413 1           char* public_buffer = safemalloc(BR_RSA_KBUF_PUB_SIZE(size));
1414 1           private_key = safemalloc(sizeof(br_rsa_private_key));
1415 1           char* private_buffer = safemalloc(BR_RSA_KBUF_PRIV_SIZE(size));
1416             C_ARGS:
1417             prng, private_key, private_buffer, key, public_buffer, size, exponent
1418             POSTCALL:
1419 1 50         if (!RETVAL)
1420 0           XSRETURN(0);
1421              
1422              
1423             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::RSA::PublicKey PREFIX = br_rsa_public_key_
1424             BOOT:
1425 50           rsa_pkcs1_verify = br_rsa_pkcs1_vrfy_get_default();
1426 50           rsa_oaep_encrypt = br_rsa_oaep_encrypt_get_default();
1427              
1428             SV* br_rsa_public_key_pkcs1_verify(Crypt::Bear::RSA::PublicKey self, hash_oid_type hash, const unsigned char* signature, size_t length(signature))
1429             CODE:
1430 1           RETVAL = make_buffer(hash->length);
1431 1           bool success = rsa_pkcs1_verify(signature, STRLEN_length_of_signature, hash->oid, hash->length, self, (unsigned char*)SvPV_nolen(RETVAL));
1432 1 50         if (!success)
1433 0           sv_setsv(RETVAL, &PL_sv_undef);
1434             OUTPUT:
1435             RETVAL
1436              
1437             SV* br_rsa_public_key_oaep_encrypt(Crypt::Bear::RSA::PublicKey self, hash_type hash, const char* plain, size_t length(plain), Crypt::Bear::PRNG prng, const char* label, size_t length(label))
1438             CODE:
1439 1           RETVAL = make_buffer(self->nlen);
1440 1           size_t length = rsa_oaep_encrypt(prng, hash, label, STRLEN_length_of_label, self, SvPV_nolen(RETVAL), self->nlen, plain, STRLEN_length_of_plain);
1441 1 50         if (length)
1442 1           SvCUR_set(RETVAL, length);
1443             else
1444 0           Perl_croak(aTHX_ "Could not encrypt");
1445             OUTPUT:
1446             RETVAL
1447              
1448              
1449              
1450             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::RSA::PrivateKey PREFIX = br_rsa_private_key_
1451             BOOT:
1452 50           rsa_pkcs1_sign = br_rsa_pkcs1_sign_get_default();
1453 50           rsa_oaep_decrypt = br_rsa_oaep_decrypt_get_default();
1454              
1455             SV* br_rsa_private_key_pkcs1_sign(Crypt::Bear::RSA::PrivateKey self, hash_oid_type hash_oid, const unsigned char* hash, size_t length(hash))
1456             CODE:
1457 1 50         if (STRLEN_length_of_hash != hash_oid->length)
1458 0           Perl_croak(aTHX_ "Hash has incorrect length");
1459 1           RETVAL = make_buffer((self->n_bitlen+7)/8);
1460 1           bool success = rsa_pkcs1_sign(hash_oid->oid, hash, STRLEN_length_of_hash, self, (unsigned char*)SvPV_nolen(RETVAL));
1461 1 50         if (!success)
1462 0           Perl_croak(aTHX_ "Could not sign");
1463             OUTPUT:
1464             RETVAL
1465              
1466             SV* br_rsa_private_key_oaep_decrypt(Crypt::Bear::RSA::PrivateKey self, hash_type hash, const char* ciphertext, size_t length(ciphertext), const char* label, size_t length(label))
1467             CODE:
1468 1           RETVAL = newSVpvn(ciphertext, STRLEN_length_of_ciphertext);
1469 1           size_t len = STRLEN_length_of_ciphertext;
1470 1           bool succes = rsa_oaep_decrypt(hash, label, STRLEN_length_of_label, self, SvPV_nolen(RETVAL), &len);
1471 1 50         if (succes)
1472 1           SvCUR_set(RETVAL, len);
1473             else
1474 0           sv_setsv(RETVAL, &PL_sv_undef);
1475             OUTPUT:
1476             RETVAL
1477              
1478              
1479             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::EC PREFIX = br_ec_
1480             BOOT:
1481 50           ec_default = br_ec_get_default();
1482 50           ec_sign_default = br_ecdsa_sign_asn1_get_default();
1483 50           ec_verify_default = br_ecdsa_vrfy_asn1_get_default();
1484              
1485             void br_ec_supported_curves(class)
1486             PPCODE:
1487 0 0         for (UV i = 0; i < 31; i++) {
1488 0 0         if (ec_default->supported_curves & (1 << i)) {
1489 0           union value value = { .integer = i };
1490 0           const entry* entry = map_reverse_find(curves, value);
1491 0 0         mXPUSHp(entry->key, entry->length);
1492             }
1493             }
1494              
1495              
1496             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::EC::PublicKey PREFIX = br_ec_public_key_
1497              
1498             Crypt::Bear::EC::PublicKey br_ec_public_key_new(curve_type curve, const char* data, size_t length(data))
1499             CODE:
1500 0           RETVAL = safemalloc(sizeof *RETVAL);
1501 0           RETVAL->curve = curve;
1502 0           RETVAL->q = saveupvn(data, STRLEN_length_of_data);
1503 0           RETVAL->qlen = STRLEN_length_of_data;
1504             OUTPUT:
1505             RETVAL
1506              
1507             curve_type br_ec_public_key_curve(Crypt::Bear::EC::PublicKey self)
1508             CODE:
1509 0           RETVAL = self->curve;
1510             OUTPUT:
1511             RETVAL
1512              
1513             bool br_ec_public_key_ecdsa_verify(Crypt::Bear::EC::PublicKey self, hash_type hash_name, unsigned char* hash_value, size_t length(hash_value), unsigned char* signature, size_t length(signature))
1514             CODE:
1515 1           size_t hash_size = ((hash_name->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK);
1516 1 50         if (STRLEN_length_of_hash_value != hash_size)
1517 0           Perl_croak(aTHX_ "Hash is inappropriately sized");
1518 1 50         RETVAL = ec_verify_default(ec_default, hash_value, hash_size, self, signature, STRLEN_length_of_signature);
1519             OUTPUT:
1520             RETVAL
1521              
1522              
1523             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::EC::PrivateKey PREFIX = br_ec_private_key_
1524              
1525             Crypt::Bear::EC::PrivateKey br_ec_private_key_new(curve_type curve, const char* data, size_t length(data))
1526             CODE:
1527 0           RETVAL = safemalloc(sizeof *RETVAL);
1528 0           RETVAL->curve = curve;
1529 0           RETVAL->x = saveupvn(data, STRLEN_length_of_data);
1530 0           RETVAL->xlen = STRLEN_length_of_data;
1531             OUTPUT:
1532             RETVAL
1533              
1534             curve_type br_ec_private_key_curve(Crypt::Bear::EC::PrivateKey self)
1535             CODE:
1536 0           RETVAL = self->curve;
1537             OUTPUT:
1538             RETVAL
1539              
1540             Crypt::Bear::EC::PrivateKey br_ec_private_key_generate(class, curve_type curve, Crypt::Bear::PRNG prng)
1541             CODE:
1542 2           RETVAL = safemalloc(sizeof *RETVAL);
1543 2           size_t length = br_ec_keygen(prng, ec_default, RETVAL, NULL, curve);
1544 2           char* buffer = safemalloc(length);
1545 2           br_ec_keygen(prng, ec_default, RETVAL, buffer, curve);
1546             OUTPUT:
1547             RETVAL
1548              
1549             Crypt::Bear::EC::PublicKey br_ec_private_key_public_key(Crypt::Bear::EC::PrivateKey self)
1550             CODE:
1551 2           RETVAL = safemalloc(sizeof *RETVAL);
1552 2           size_t length = br_ec_compute_pub(ec_default, RETVAL, NULL, self);
1553 2           char* buffer = safemalloc(length);
1554 2           br_ec_compute_pub(ec_default, RETVAL, buffer, self);
1555             OUTPUT:
1556             RETVAL
1557              
1558             SV* br_ec_private_key_ecdsa_sign(Crypt::Bear::EC::PrivateKey self, hash_type hash_name, unsigned char* hash_value, size_t length(hash_value))
1559             CODE:
1560 1           size_t hash_size = ((hash_name->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK);
1561 1 50         if (STRLEN_length_of_hash_value != hash_size)
1562 0           Perl_croak(aTHX_ "Hash is inappropriately sized");
1563 1           RETVAL = make_buffer(ecdsa_max_size);
1564 1           size_t length = ec_sign_default(ec_default, hash_name, hash_value, self, SvPV_nolen(RETVAL));
1565 1 50         if (!length)
1566 0           Perl_croak(aTHX_ "Could not sign");
1567 1           SvCUR_set(RETVAL, length);
1568             OUTPUT:
1569             RETVAL
1570              
1571             SV* br_ec_private_key_ecdh_key_exchange(Crypt::Bear::EC::PrivateKey self, Crypt::Bear::EC::PublicKey other)
1572             CODE:
1573 2 50         if (self->curve != other->curve)
1574 0           Perl_croak(aTHX_ "Keys must be on same curve for EC key exchange");
1575              
1576 2           size_t out_length = 0;
1577 2           (ec_default->generator)(self->curve, &out_length);
1578 2           RETVAL = make_buffer(out_length);
1579 2           memcpy(SvPV_nolen(RETVAL), other->q, other->qlen);
1580              
1581 2           (ec_default->mul)(SvPV_nolen(RETVAL), other->qlen, self->x, self->xlen, self->curve);
1582             size_t xoff, xlen;
1583 2           xoff = ec_default->xoff(self->curve, &xlen);
1584 2 50         if (xoff)
1585 2           sv_chop(RETVAL, SvPV_nolen(RETVAL) + xoff);
1586 2           SvCUR_set(RETVAL, xlen);
1587             OUTPUT:
1588             RETVAL
1589              
1590             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::PEM PREFIX = br_pem_
1591              
1592             SV* br_pem_pem_encode(const char* banner, const char* data, size_t length(data), ...)
1593             CODE:
1594 1           unsigned flags = 0;
1595 1 50         for (int i = 3; i < items; i++) {
1596 0           flags |= lookup_pem_flag(ST(i));
1597             }
1598 1           size_t length = br_pem_encode(NULL, data, STRLEN_length_of_data, banner, flags);
1599 1           RETVAL = make_buffer(length);
1600 1           br_pem_encode(SvPV_nolen(RETVAL), data, STRLEN_length_of_data, banner, flags);
1601             OUTPUT:
1602             RETVAL
1603              
1604              
1605             SV* br_pem_pem_decode(const char* data, size_t length(data))
1606             PPCODE:
1607             pem_decoder decoder;
1608 11           br_pem_decoder_init(&decoder.decoder);
1609             #ifdef MULTIPLICITY
1610             decoder.aTHX = aTHX;
1611             #endif
1612              
1613 11           size_t left = STRLEN_length_of_data;
1614 317 100         while (left) {
1615 306           size_t pushed = br_pem_decoder_push(&decoder.decoder, data, left);
1616 306           data += pushed;
1617 306           left -= pushed;
1618              
1619 306           switch (br_pem_decoder_event(&decoder.decoder)) {
1620 153           case BR_PEM_BEGIN_OBJ: {
1621 153           decoder.name = newSVpv(br_pem_decoder_name(&decoder.decoder), 0);
1622 153           decoder.buffer = newSVpvn("", 0);
1623 153           br_pem_decoder_setdest(&decoder.decoder, pem_callback, &decoder);
1624 153           break;
1625             }
1626 153           case BR_PEM_END_OBJ: {
1627 153 50         if (decoder.buffer) {
1628 153 50         mXPUSHs(decoder.name);
1629 153 50         mXPUSHs(decoder.buffer);
1630 153           decoder.name = NULL;
1631 153           decoder.buffer = NULL;
1632             }
1633 153           break;
1634             }
1635 0           case BR_PEM_ERROR: {
1636 0 0         if (decoder.name)
1637 0           SvREFCNT_dec(decoder.name);
1638 0 0         if (decoder.buffer)
1639 0           SvREFCNT_dec(decoder.buffer);
1640 0           Perl_croak(aTHX_ "Could not parse PEM");
1641             break;
1642             }
1643             }
1644             }
1645              
1646             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::PEM::Decoder PREFIX = br_pem_decoder_
1647              
1648             Crypt::Bear::PEM::Decoder br_pem_decoder_new(class, SV* callback)
1649             CODE:
1650 2           RETVAL = safemalloc(sizeof *RETVAL);
1651 2           br_pem_decoder_init(&RETVAL->decoder);
1652 2           RETVAL->callback = SvREFCNT_inc(callback);
1653 2           RETVAL->name = NULL;
1654 2           RETVAL->buffer = NULL;
1655             #ifdef MULTIPLICITY
1656             RETVAL->aTHX = aTHX;
1657             #endif
1658             OUTPUT:
1659             RETVAL
1660              
1661             void br_pem_decoder_push(Crypt::Bear::PEM::Decoder self, const char* data, size_t length(data))
1662             CODE:
1663 45           size_t left = STRLEN_length_of_data;
1664 90 100         while (left) {
1665 45           size_t pushed = br_pem_decoder_push(&self->decoder, data, left);
1666 45           data += pushed;
1667 45           left -= pushed;
1668              
1669 45           switch (br_pem_decoder_event(&self->decoder)) {
1670 2           case BR_PEM_BEGIN_OBJ: {
1671 2           self->name = newSVpv(br_pem_decoder_name(&self->decoder), 0);
1672 2           self->buffer = newSVpvn("", 0);
1673 2           br_pem_decoder_setdest(&self->decoder, pem_callback, self);
1674 2           break;
1675             }
1676 2           case BR_PEM_END_OBJ: {
1677 2 50         if (self->buffer) {
1678 2           ENTER;
1679 2           SAVETMPS;
1680 2 50         PUSHMARK(SP);
1681 2 50         mXPUSHs(self->name);
1682 2 50         mXPUSHs(self->buffer);
1683 2           PUTBACK;
1684 2           call_sv(self->callback, G_VOID | G_DISCARD);
1685 2           SPAGAIN;
1686 2 50         FREETMPS;
1687 2           LEAVE;
1688 2           self->name = NULL;
1689 2           self->buffer = NULL;
1690             }
1691 2           break;
1692             }
1693 0           case BR_PEM_ERROR: {
1694 0 0         if (self->buffer) {
1695 0           SvREFCNT_dec(self->buffer);
1696 0           self->buffer = NULL;
1697             }
1698 0           Perl_croak(aTHX_ "Could not parse PEM");
1699             break;
1700             }
1701             }
1702             }
1703              
1704             bool br_pem_decoder_entry_in_progress(Crypt::Bear::PEM::Decoder self)
1705             CODE:
1706 0 0         RETVAL = self->buffer != NULL;
1707             OUTPUT:
1708             RETVAL
1709              
1710             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::X509::Certificate PREFIX = br_x509_certificate_
1711              
1712             Crypt::Bear::X509::Certificate br_x509_certificate_new(class, const unsigned char* data, size_t length(data))
1713             CODE:
1714 152           RETVAL = safemalloc(sizeof(struct certificate));
1715              
1716 152           SV* dn = sv_2mortal(newSVpvn("", 0));
1717 152           struct decoder_helper helper = {
1718             #ifdef MULTIPLICITY
1719             .aTHX = aTHX,
1720             #endif
1721             .value = dn,
1722             };
1723 152           br_x509_decoder_init(&RETVAL->decoder, dn_decoder, &helper);
1724 152           br_x509_decoder_push(&RETVAL->decoder, data, STRLEN_length_of_data);
1725              
1726 152           br_error_type error = br_x509_decoder_last_error(&RETVAL->decoder);
1727 152 50         if (error != 0) {
1728 0           Safefree(RETVAL);
1729 0           Perl_croak(aTHX_ "Could not decode certificate: %s", lookup_error(error));
1730             }
1731              
1732 152           RETVAL->dn.data = (unsigned char*)savesvpv(dn);
1733 152           RETVAL->dn.len = SvCUR(dn);
1734              
1735 152           br_x509_certificate_init(&RETVAL->cert, data, STRLEN_length_of_data);
1736             OUTPUT:
1737             RETVAL
1738              
1739             SV* br_x509_certificate_dn(Crypt::Bear::X509::Certificate self)
1740              
1741             SV* br_x509_certificate_public_key(Crypt::Bear::X509::Certificate self)
1742             CODE:
1743 4           br_x509_pkey* result = br_x509_decoder_get_pkey(&self->decoder);
1744 4           RETVAL = x509_key_unpack(result);
1745             OUTPUT:
1746             RETVAL
1747              
1748             bool br_x509_certificate_is_ca(Crypt::Bear::X509::Certificate self)
1749              
1750             key_kind_type br_x509_certificate_signer_key_type(Crypt::Bear::X509::Certificate self)
1751              
1752              
1753              
1754             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::X509::PrivateKey PREFIX = br_x509_private_key_
1755              
1756             Crypt::Bear::X509::PrivateKey br_x509_private_key_new(class, const char* data, size_t length(data))
1757             CODE:
1758             br_skey_decoder_context context;
1759 2           br_skey_decoder_init(&context);
1760 2           br_skey_decoder_push(&context, data, STRLEN_length_of_data);
1761              
1762 2           br_error_type error = br_skey_decoder_last_error(&context);
1763 2 50         if (error != 0)
1764 0           Perl_croak(aTHX_ "Could not decode private key: %s", lookup_error(error));
1765              
1766 2           RETVAL = safemalloc(sizeof *RETVAL);
1767              
1768 2           RETVAL->key_type = br_skey_decoder_key_type(&context);
1769 2 50         if (RETVAL->key_type == BR_KEYTYPE_RSA) {
1770 2           rsa_private_key_copy(&RETVAL->rsa, br_skey_decoder_get_rsa(&context));
1771 0 0         } else if (RETVAL->key_type == BR_KEYTYPE_EC) {
1772 0           ec_private_key_copy(&RETVAL->ec, br_skey_decoder_get_ec(&context));
1773             }
1774             OUTPUT:
1775             RETVAL
1776              
1777              
1778             SV* br_x509_private_key_unpack(Crypt::Bear::X509::PrivateKey self)
1779             CODE:
1780 0           RETVAL = &PL_sv_undef;
1781 0 0         if (self->key_type == BR_KEYTYPE_RSA) {
1782 0           br_rsa_private_key* key = safemalloc(sizeof *key);
1783 0           rsa_private_key_copy(key, &self->rsa);
1784 0           RETVAL = make_magic(key, "Crypt::Bear::RSA::PrivateKey", &Crypt__Bear__RSA__PrivateKey_magic);
1785 0 0         } else if (self->key_type == BR_KEYTYPE_EC) {
1786 0           br_ec_private_key* key = safemalloc(sizeof *key);
1787 0           ec_private_key_copy(key, &self->ec);
1788 0           RETVAL = make_magic(key, "Crypt::Bear::EC::PrivateKey", &Crypt__Bear__EC__PrivateKey_magic);
1789             }
1790             OUTPUT:
1791             RETVAL
1792              
1793              
1794             key_kind_type br_x509_private_key_type(Crypt::Bear::X509::PrivateKey self)
1795             CODE:
1796 0           RETVAL = self->key_type;
1797             OUTPUT:
1798             RETVAL
1799              
1800              
1801              
1802             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::X509::TrustAnchors PREFIX = br_x509_trust_anchors_
1803              
1804             Crypt::Bear::X509::TrustAnchors br_x509_trust_anchors_new(class)
1805             CODE:
1806 4           RETVAL = safemalloc(sizeof *RETVAL);
1807 4           trust_anchors_init(RETVAL);
1808             OUTPUT:
1809             RETVAL
1810              
1811             void br_x509_trust_anchors_add(Crypt::Bear::X509::TrustAnchors self, Crypt::Bear::X509::Certificate certificate, bool is_ca = br_x509_decoder_isCA(&certificate->decoder))
1812             CODE:
1813 146           br_x509_trust_anchor anchor = { .flags = is_ca ? BR_X509_TA_CA : 0};
1814 146           dn_copy(&anchor.dn, &certificate->dn);
1815 146           x509_key_copy(&anchor.pkey, br_x509_decoder_get_pkey(&certificate->decoder));
1816 146           trust_anchors_push(self, &anchor);
1817              
1818             void br_x509_trust_anchors_merge(Crypt::Bear::X509::TrustAnchors self, Crypt::Bear::X509::TrustAnchors other)
1819             CODE:
1820 3 100         for (size_t i = 0; i < other->used; i++) {
1821 2           const br_x509_trust_anchor* old = other->array + i;
1822 2           br_x509_trust_anchor anchor = { .flags = old->flags };
1823 2           dn_copy(&anchor.dn, &old->dn);
1824 2           x509_key_copy(&anchor.pkey, &old->pkey);
1825 2           trust_anchors_push(self, &anchor);
1826             }
1827              
1828             void br_x509_trust_anchors_names(Crypt::Bear::X509::TrustAnchors self)
1829             PPCODE:
1830 0 0         for (size_t i = 0; i < self->used; i++) {
1831 0           const br_x509_trust_anchor* anchor = self->array + i;
1832 0 0         mXPUSHp((const char*)anchor->dn.data, anchor->dn.len);
1833             }
1834              
1835             UV br_x509_trust_anchors_count(Crypt::Bear::X509::TrustAnchors self)
1836             CODE:
1837 6 50         RETVAL = self->used;
1838             OUTPUT:
1839             RETVAL
1840              
1841             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::X509::Validator PREFIX = br_x509_validator_
1842              
1843             void start_chain(Crypt::Bear::X509::Validator self, const char* server_name)
1844             CODE:
1845 0           ((*self)->start_chain)(self, server_name);
1846              
1847             void start_certificate(Crypt::Bear::X509::Validator self, size_t length)
1848             CODE:
1849 0           ((*self)->start_cert)(self, length);
1850              
1851             void append(Crypt::Bear::X509::Validator self, const unsigned char* data, size_t length(data))
1852             CODE:
1853 0           ((*self)->append)(self, data, STRLEN_length_of_data);
1854              
1855             void end_certificate(Crypt::Bear::X509::Validator self)
1856             CODE:
1857 0           ((*self)->end_cert)(self);
1858              
1859             void end_chain(Crypt::Bear::X509::Validator self)
1860             CODE:
1861 0           ((*self)->end_chain)(self);
1862              
1863             SV* get_pkey(Crypt::Bear::X509::Validator self, unsigned wanted_usage)
1864             CODE:
1865             unsigned usage;
1866 0           const br_x509_pkey* public_key = ((*self)->get_pkey)(self, &usage);
1867              
1868 0 0         if (wanted_usage && (usage & wanted_usage) != wanted_usage)
    0          
1869 0           RETVAL = &PL_sv_undef;
1870 0 0         else if (public_key)
1871 0           RETVAL = x509_key_unpack(public_key);
1872             else
1873 0           RETVAL = &PL_sv_undef;
1874             OUTPUT:
1875             RETVAL
1876              
1877             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::X509::Validator::Minimal PREFIX = br_x509_minimal_
1878             BOOT:
1879 50           push_isa(Crypt::Bear::X509::Validator::Minimal, Crypt::Bear::X509::Validator);
1880              
1881             Crypt::Bear::X509::Validator::Minimal br_x509_minimal_new(SV* class, Crypt::Bear::X509::TrustAnchors anchors)
1882             CODE:
1883 0           RETVAL = safemalloc(sizeof *RETVAL);
1884 0           trust_anchors_copy(&RETVAL->anchors, anchors);
1885 0           br_x509_minimal_init_full(&RETVAL->context, RETVAL->anchors.array, RETVAL->anchors.used);
1886             OUTPUT:
1887             RETVAL
1888              
1889             #if 0
1890             void br_x509_minimal_set_time(Crypt::Bear::X509::Validator::Minimal self, UV days, UV seconds)
1891              
1892             void br_x509_minimal_set_minrsa(Crypt::Bear::X509::Validator::Minimal self, UV size)
1893             #endif
1894              
1895              
1896             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::X509::Validator::KnownKey PREFIX = br_x509_knownkey_
1897             BOOT:
1898 50           push_isa(Crypt::Bear::X509::Validator::KnownKey, Crypt::Bear::X509::Validator);
1899            
1900              
1901              
1902             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::SSL
1903              
1904              
1905              
1906             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::SSL::Session PREFIX = br_ssl_session_
1907              
1908              
1909              
1910             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::X509::Certificate::Chain PREFIX = br_x509_certificate_chain_
1911              
1912             Crypt::Bear::X509::Certificate::Chain br_x509_certificate_chain_new(class)
1913             CODE:
1914 2           RETVAL = safemalloc(sizeof *RETVAL);
1915 2           certificate_chain_init(RETVAL);
1916             OUTPUT:
1917             RETVAL
1918              
1919             void br_x509_certificate_chain_add(Crypt::Bear::X509::Certificate::Chain self, Crypt::Bear::X509::Certificate certificate)
1920             CODE:
1921             br_x509_certificate entry;
1922 2           br_x509_certificate_copy(&entry, &certificate->cert);
1923 2           certificate_chain_push(self, &entry);
1924 2 50         if (self->used == 1)
1925 2           self->signer_key_type = br_x509_decoder_get_signer_key_type(&certificate->decoder);
1926              
1927              
1928             UV br_x509_certificate_chain_count(Crypt::Bear::X509::Certificate::Chain self)
1929             CODE:
1930 2 50         RETVAL = self->used;
1931             OUTPUT:
1932             RETVAL
1933              
1934              
1935              
1936             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::SSL::PrivateCertificate PREFIX = br_ssl_private_certificate_
1937              
1938             Crypt::Bear::SSL::PrivateCertificate br_ssl_private_certificate_new(class, Crypt::Bear::X509::Certificate::Chain certs, Crypt::Bear::X509::PrivateKey key, usage_type usage = automatic)
1939             CODE:
1940 1           RETVAL = safemalloc(sizeof *RETVAL);
1941 1           certificate_chain_copy(&RETVAL->chain, certs);
1942 1           private_key_copy(&RETVAL->key, key);
1943 1           RETVAL->usage = usage;
1944             OUTPUT:
1945             RETVAL
1946              
1947             Crypt::Bear::X509::Certificate::Chain br_ssl_private_certificate_chain(Crypt::Bear::SSL::PrivateCertificate self)
1948             CODE:
1949 1           RETVAL = safemalloc(sizeof *RETVAL);
1950 1           certificate_chain_copy(RETVAL, &self->chain);
1951             OUTPUT:
1952             RETVAL
1953              
1954             Crypt::Bear::X509::PrivateKey br_ssl_private_certificate_key(Crypt::Bear::SSL::PrivateCertificate self)
1955             CODE:
1956 0           RETVAL = safemalloc(sizeof *RETVAL);
1957 0           private_key_copy(RETVAL, &self->key);
1958             OUTPUT:
1959             RETVAL
1960              
1961              
1962             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::SSL::Engine PREFIX = br_ssl_engine_
1963              
1964             const char* br_ssl_engine_get_server_name(Crypt::Bear::SSL::Engine self)
1965              
1966             ssl_version_type br_ssl_engine_get_version(Crypt::Bear::SSL::Engine self)
1967              
1968             void br_ssl_engine_set_versions(Crypt::Bear::SSL::Engine self, ssl_version_type min, ssl_version_type max)
1969              
1970             curve_type br_ssl_engine_get_ecdhe_curve(Crypt::Bear::SSL::Engine self)
1971              
1972             br_error_type br_ssl_engine_last_error(Crypt::Bear::SSL::Engine self)
1973              
1974             void br_ssl_engine_inject_entropy(Crypt::Bear::SSL::Engine self, const char* data, size_t length(data))
1975              
1976             Crypt::Bear::SSL::Session br_ssl_engine_get_session_parameters(Crypt::Bear::SSL::Engine self)
1977             CODE:
1978 0           RETVAL = safemalloc(sizeof *RETVAL);
1979 0           br_ssl_engine_get_session_parameters(self, RETVAL);
1980             OUTPUT:
1981             RETVAL
1982              
1983             void br_ssl_engine_set_session_parameters(Crypt::Bear::SSL::Engine self, Crypt::Bear::SSL::Session pp)
1984              
1985             bool br_ssl_engine_is_closed(Crypt::Bear::SSL::Engine self)
1986             CODE:
1987 6 100         RETVAL = br_ssl_engine_current_state(self) == BR_SSL_CLOSED;
1988             OUTPUT:
1989             RETVAL
1990              
1991             bool br_ssl_engine_send_ready(Crypt::Bear::SSL::Engine self)
1992             CODE:
1993 3 100         RETVAL = cBOOL(br_ssl_engine_current_state(self) & BR_SSL_SENDAPP);
1994             OUTPUT:
1995             RETVAL
1996              
1997             SV* br_ssl_engine_push_received(Crypt::Bear::SSL::Engine self, unsigned char* data, size_t length(data))
1998             CODE:
1999 8           RETVAL = newSVpvn("", 0);
2000 8           size_t offset = 0;
2001              
2002 8 50         while (br_ssl_engine_current_state(self) & BR_SSL_RECVAPP) {
2003 0           size_t len = 0;
2004 0           unsigned char* buffer = br_ssl_engine_recvapp_buf(self, &len);
2005              
2006 0           sv_catpvn(RETVAL, (const char*)buffer, len);
2007 0           br_ssl_engine_recvapp_ack(self, len);
2008             }
2009              
2010             do {
2011 22 50         if (br_ssl_engine_current_state(self) == BR_SSL_CLOSED)
2012 0           Perl_croak(aTHX_ "Connection is closed");
2013              
2014 22           size_t len = 0;
2015 22           unsigned char* buffer = br_ssl_engine_recvrec_buf(self, &len);
2016              
2017 22 50         if (len) {
2018 22           size_t available = STRLEN_length_of_data - offset;
2019              
2020 22 50         if (len > available)
2021 0           len = available;
2022              
2023 22           memcpy(buffer, data + offset, len);
2024 22           offset += len;
2025 22           br_ssl_engine_recvrec_ack(self, len);
2026             }
2027              
2028 24 100         while (br_ssl_engine_current_state(self) & BR_SSL_RECVAPP) {
2029 2           size_t len = 0;
2030 2           unsigned char* buffer = br_ssl_engine_recvapp_buf(self, &len);
2031              
2032 2           sv_catpvn(RETVAL, (const char*)buffer, len);
2033 2           br_ssl_engine_recvapp_ack(self, len);
2034             }
2035 22 100         } while (offset < STRLEN_length_of_data);
2036             OUTPUT:
2037             RETVAL
2038              
2039             SV* br_ssl_engine_push_send(Crypt::Bear::SSL::Engine self, unsigned char* data, size_t length(data), bool flush = FALSE)
2040             CODE:
2041 2           RETVAL = newSVpvn("", 0);
2042 2           size_t offset = 0;
2043              
2044             do {
2045 2 50         while (br_ssl_engine_current_state(self) & BR_SSL_SENDREC) {
2046 0           size_t len = 0;
2047 0           unsigned char* buffer = br_ssl_engine_sendrec_buf(self, &len);
2048              
2049 0           sv_catpvn(RETVAL, (const char*)buffer, len);
2050 0           br_ssl_engine_sendrec_ack(self, len);
2051             }
2052              
2053 2 50         if (br_ssl_engine_current_state(self) == BR_SSL_CLOSED)
2054 0           Perl_croak(aTHX_ "Connection is closed");
2055              
2056 2           size_t len = 0;
2057 2           unsigned char* buffer = br_ssl_engine_sendapp_buf(self, &len);
2058              
2059 2 50         if (len && STRLEN_length_of_data) {
    50          
2060 2           size_t available = STRLEN_length_of_data - offset;
2061              
2062 2 50         if (len > available)
2063 2           len = available;
2064              
2065 2           memcpy(buffer, data + offset, len);
2066 2           offset += len;
2067 2           br_ssl_engine_sendapp_ack(self, len);
2068             }
2069 2 50         } while (offset < STRLEN_length_of_data);
2070              
2071 2 50         if (flush)
2072 2           br_ssl_engine_flush(self, FALSE);
2073              
2074 4 100         while (br_ssl_engine_current_state(self) & BR_SSL_SENDREC) {
2075 2           size_t len = 0;
2076 2           unsigned char* buffer = br_ssl_engine_sendrec_buf(self, &len);
2077              
2078 2           sv_catpvn(RETVAL, (const char*)buffer, len);
2079 2           br_ssl_engine_sendrec_ack(self, len);
2080             }
2081             OUTPUT:
2082             RETVAL
2083              
2084             SV* br_ssl_engine_pull_send(Crypt::Bear::SSL::Engine self, bool force = FALSE)
2085             CODE:
2086 6           RETVAL = newSVpvn("", 0);
2087              
2088 6           br_ssl_engine_flush(self, force);
2089              
2090 15 100         while (br_ssl_engine_current_state(self) & BR_SSL_SENDREC) {
2091 9           size_t len = 0;
2092 9           unsigned char* buffer = br_ssl_engine_sendrec_buf(self, &len);
2093              
2094 9           sv_catpvn(RETVAL, (const char*)buffer, len);
2095 9           br_ssl_engine_sendrec_ack(self, len);
2096             }
2097             OUTPUT:
2098             RETVAL
2099              
2100              
2101             void br_ssl_engine_close(Crypt::Bear::SSL::Engine self)
2102              
2103              
2104             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::SSL::Client PREFIX = br_ssl_client_
2105             BOOT:
2106 50           push_isa(Crypt::Bear::SSL::Client, Crypt::Bear::SSL::Engine);
2107              
2108             Crypt::Bear::SSL::Client br_ssl_client_new(class, Crypt::Bear::X509::TrustAnchors anchors)
2109             CODE:
2110 1           RETVAL = safemalloc(sizeof *RETVAL);
2111 1           trust_anchors_copy(&RETVAL->trust_anchors, anchors);
2112 1           br_ssl_client_init_full(&RETVAL->context, &RETVAL->minimal, RETVAL->trust_anchors.array, RETVAL->trust_anchors.used);
2113 1           br_ssl_engine_set_buffer(&RETVAL->context.eng, RETVAL->buffer, sizeof RETVAL->buffer, true);
2114 1           private_certificate_init(&RETVAL->private);
2115             OUTPUT:
2116             RETVAL
2117              
2118             bool br_ssl_client_reset(Crypt::Bear::SSL::Client self, SV* server_name, bool resume_session = FALSE);
2119             CODE:
2120 1 50         if (SvOK(server_name))
2121 1           RETVAL = br_ssl_client_reset(&self->context, SvPV_nolen(server_name), resume_session);
2122             else
2123 0           RETVAL = br_ssl_client_reset(&self->context, NULL, resume_session);
2124             OUTPUT:
2125             RETVAL
2126              
2127              
2128             void br_ssl_client_set_client_certificate(Crypt::Bear::SSL::Client self, Crypt::Bear::SSL::PrivateCertificate priv_cert)
2129             CODE:
2130 0           private_certificate_copy(&self->private, priv_cert);
2131              
2132 0 0         if (priv_cert->key.key_type == BR_KEYTYPE_RSA) {
2133 0           br_ssl_client_set_single_rsa(&self->context, self->private.chain.array, self->private.chain.used, &self->private.key.rsa, rsa_pkcs1_sign);
2134 0 0         } else if (priv_cert->key.key_type == BR_KEYTYPE_EC) {
2135 0           br_ssl_client_set_single_ec(&self->context, self->private.chain.array, self->private.chain.used, &self->private.key.ec, self->private.usage, priv_cert->chain.signer_key_type, ec_default, ec_sign_default);
2136             } else {
2137 0           Perl_croak(aTHX_ "Invalid private key");
2138             }
2139              
2140             void br_ssl_client_forget_session(Crypt::Bear::SSL::Client self)
2141             CODE:
2142 0           br_ssl_client_forget_session(&self->context);
2143              
2144              
2145             MODULE = Crypt::Bear PACKAGE = Crypt::Bear::SSL::Server PREFIX = br_ssl_server_
2146             BOOT:
2147 50           push_isa(Crypt::Bear::SSL::Server, Crypt::Bear::SSL::Engine);
2148              
2149             Crypt::Bear::SSL::Server br_ssl_server_new(class, Crypt::Bear::SSL::PrivateCertificate priv_cert)
2150             CODE:
2151 1           RETVAL = safemalloc(sizeof *RETVAL);
2152 1           private_certificate_copy(&RETVAL->private, priv_cert);
2153              
2154 1 50         if (priv_cert->key.key_type == BR_KEYTYPE_RSA) {
2155 1           br_ssl_server_init_full_rsa(&RETVAL->context, RETVAL->private.chain.array, RETVAL->private.chain.used, &RETVAL->private.key.rsa);
2156 0 0         } else if (priv_cert->key.key_type == BR_KEYTYPE_EC) {
2157 0           br_ssl_server_init_full_ec(&RETVAL->context, RETVAL->private.chain.array, RETVAL->private.chain.used, priv_cert->chain.signer_key_type, &RETVAL->private.key.ec);
2158             } else {
2159 0           Safefree(RETVAL);
2160 0           Perl_croak(aTHX_ "Invalid private key");
2161             }
2162 1           br_ssl_engine_set_buffer(&RETVAL->context.eng, RETVAL->buffer, BR_SSL_BUFSIZE_BIDI, true);
2163              
2164 1           unsigned error = br_ssl_engine_last_error(&RETVAL->context.eng);
2165 1 50         if (error) {
2166 0           Safefree(RETVAL);
2167 0           Perl_croak(aTHX_ "Could not instantiate server: %s", lookup_error(error));
2168             }
2169             OUTPUT:
2170             RETVAL
2171              
2172             void br_ssl_server_get_client_suites(Crypt::Bear::SSL::Server self)
2173             PPCODE:
2174             size_t len;
2175 0           const br_suite_translated* suites = br_ssl_server_get_client_suites(&self->context, &len);
2176 0 0         for (size_t i = 0; i < len; i++) {
2177 0           AV* pair = newAV();
2178 0           av_push(pair, newSVuv(suites[i][0]));
2179 0           av_push(pair, newSVuv(suites[i][1]));
2180 0 0         mXPUSHs(newRV_noinc((SV*)pair));
2181             }
2182              
2183              
2184             bool br_ssl_server_reset(Crypt::Bear::SSL::Server self);
2185             CODE:
2186 1 50         RETVAL = br_ssl_server_reset(&self->context);
2187             OUTPUT:
2188             RETVAL
2189