Crypt-Bear
view release on metacpan or search on metacpan
lib/Crypt/Bear.xs view on Meta::CPAN
rsa_oaep_encrypt = br_rsa_oaep_encrypt_get_default();
SV* br_rsa_public_key_pkcs1_verify(Crypt::Bear::RSA::PublicKey self, hash_oid_type hash, const unsigned char* signature, size_t length(signature))
CODE:
RETVAL = make_buffer(hash->length);
bool success = rsa_pkcs1_verify(signature, STRLEN_length_of_signature, hash->oid, hash->length, self, (unsigned char*)SvPV_nolen(RETVAL));
if (!success)
sv_setsv(RETVAL, &PL_sv_undef);
OUTPUT:
RETVAL
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))
CODE:
RETVAL = make_buffer(self->nlen);
size_t length = rsa_oaep_encrypt(prng, hash, label, STRLEN_length_of_label, self, SvPV_nolen(RETVAL), self->nlen, plain, STRLEN_length_of_plain);
if (length)
SvCUR_set(RETVAL, length);
else
Perl_croak(aTHX_ "Could not encrypt");
OUTPUT:
RETVAL
MODULE = Crypt::Bear PACKAGE = Crypt::Bear::RSA::PrivateKey PREFIX = br_rsa_private_key_
BOOT:
rsa_pkcs1_sign = br_rsa_pkcs1_sign_get_default();
rsa_oaep_decrypt = br_rsa_oaep_decrypt_get_default();
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))
CODE:
if (STRLEN_length_of_hash != hash_oid->length)
Perl_croak(aTHX_ "Hash has incorrect length");
RETVAL = make_buffer((self->n_bitlen+7)/8);
bool success = rsa_pkcs1_sign(hash_oid->oid, hash, STRLEN_length_of_hash, self, (unsigned char*)SvPV_nolen(RETVAL));
if (!success)
Perl_croak(aTHX_ "Could not sign");
OUTPUT:
RETVAL
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))
CODE:
RETVAL = newSVpvn(ciphertext, STRLEN_length_of_ciphertext);
size_t len = STRLEN_length_of_ciphertext;
bool succes = rsa_oaep_decrypt(hash, label, STRLEN_length_of_label, self, SvPV_nolen(RETVAL), &len);
if (succes)
SvCUR_set(RETVAL, len);
else
sv_setsv(RETVAL, &PL_sv_undef);
OUTPUT:
RETVAL
MODULE = Crypt::Bear PACKAGE = Crypt::Bear::EC PREFIX = br_ec_
BOOT:
ec_default = br_ec_get_default();
ec_sign_default = br_ecdsa_sign_asn1_get_default();
ec_verify_default = br_ecdsa_vrfy_asn1_get_default();
void br_ec_supported_curves(class)
PPCODE:
for (UV i = 0; i < 31; i++) {
if (ec_default->supported_curves & (1 << i)) {
union value value = { .integer = i };
const entry* entry = map_reverse_find(curves, value);
mXPUSHp(entry->key, entry->length);
}
}
MODULE = Crypt::Bear PACKAGE = Crypt::Bear::EC::PublicKey PREFIX = br_ec_public_key_
Crypt::Bear::EC::PublicKey br_ec_public_key_new(curve_type curve, const char* data, size_t length(data))
CODE:
RETVAL = safemalloc(sizeof *RETVAL);
RETVAL->curve = curve;
RETVAL->q = saveupvn(data, STRLEN_length_of_data);
RETVAL->qlen = STRLEN_length_of_data;
OUTPUT:
RETVAL
curve_type br_ec_public_key_curve(Crypt::Bear::EC::PublicKey self)
CODE:
RETVAL = self->curve;
OUTPUT:
RETVAL
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))
CODE:
size_t hash_size = ((hash_name->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK);
if (STRLEN_length_of_hash_value != hash_size)
Perl_croak(aTHX_ "Hash is inappropriately sized");
RETVAL = ec_verify_default(ec_default, hash_value, hash_size, self, signature, STRLEN_length_of_signature);
OUTPUT:
RETVAL
MODULE = Crypt::Bear PACKAGE = Crypt::Bear::EC::PrivateKey PREFIX = br_ec_private_key_
Crypt::Bear::EC::PrivateKey br_ec_private_key_new(curve_type curve, const char* data, size_t length(data))
CODE:
RETVAL = safemalloc(sizeof *RETVAL);
RETVAL->curve = curve;
RETVAL->x = saveupvn(data, STRLEN_length_of_data);
RETVAL->xlen = STRLEN_length_of_data;
OUTPUT:
RETVAL
curve_type br_ec_private_key_curve(Crypt::Bear::EC::PrivateKey self)
CODE:
RETVAL = self->curve;
OUTPUT:
RETVAL
Crypt::Bear::EC::PrivateKey br_ec_private_key_generate(class, curve_type curve, Crypt::Bear::PRNG prng)
CODE:
RETVAL = safemalloc(sizeof *RETVAL);
size_t length = br_ec_keygen(prng, ec_default, RETVAL, NULL, curve);
char* buffer = safemalloc(length);
br_ec_keygen(prng, ec_default, RETVAL, buffer, curve);
OUTPUT:
RETVAL
Crypt::Bear::EC::PublicKey br_ec_private_key_public_key(Crypt::Bear::EC::PrivateKey self)
CODE:
RETVAL = safemalloc(sizeof *RETVAL);
size_t length = br_ec_compute_pub(ec_default, RETVAL, NULL, self);
char* buffer = safemalloc(length);
br_ec_compute_pub(ec_default, RETVAL, buffer, self);
OUTPUT:
RETVAL
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))
CODE:
size_t hash_size = ((hash_name->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK);
if (STRLEN_length_of_hash_value != hash_size)
Perl_croak(aTHX_ "Hash is inappropriately sized");
RETVAL = make_buffer(ecdsa_max_size);
size_t length = ec_sign_default(ec_default, hash_name, hash_value, self, SvPV_nolen(RETVAL));
if (!length)
Perl_croak(aTHX_ "Could not sign");
SvCUR_set(RETVAL, length);
OUTPUT:
RETVAL
SV* br_ec_private_key_ecdh_key_exchange(Crypt::Bear::EC::PrivateKey self, Crypt::Bear::EC::PublicKey other)
CODE:
if (self->curve != other->curve)
Perl_croak(aTHX_ "Keys must be on same curve for EC key exchange");
size_t out_length = 0;
(ec_default->generator)(self->curve, &out_length);
RETVAL = make_buffer(out_length);
memcpy(SvPV_nolen(RETVAL), other->q, other->qlen);
(ec_default->mul)(SvPV_nolen(RETVAL), other->qlen, self->x, self->xlen, self->curve);
size_t xoff, xlen;
xoff = ec_default->xoff(self->curve, &xlen);
if (xoff)
sv_chop(RETVAL, SvPV_nolen(RETVAL) + xoff);
SvCUR_set(RETVAL, xlen);
OUTPUT:
RETVAL
MODULE = Crypt::Bear PACKAGE = Crypt::Bear::PEM PREFIX = br_pem_
SV* br_pem_pem_encode(const char* banner, const char* data, size_t length(data), ...)
CODE:
unsigned flags = 0;
for (int i = 3; i < items; i++) {
flags |= lookup_pem_flag(ST(i));
}
size_t length = br_pem_encode(NULL, data, STRLEN_length_of_data, banner, flags);
RETVAL = make_buffer(length);
br_pem_encode(SvPV_nolen(RETVAL), data, STRLEN_length_of_data, banner, flags);
OUTPUT:
RETVAL
SV* br_pem_pem_decode(const char* data, size_t length(data))
PPCODE:
pem_decoder decoder;
br_pem_decoder_init(&decoder.decoder);
#ifdef MULTIPLICITY
decoder.aTHX = aTHX;
#endif
size_t left = STRLEN_length_of_data;
while (left) {
size_t pushed = br_pem_decoder_push(&decoder.decoder, data, left);
data += pushed;
left -= pushed;
switch (br_pem_decoder_event(&decoder.decoder)) {
case BR_PEM_BEGIN_OBJ: {
decoder.name = newSVpv(br_pem_decoder_name(&decoder.decoder), 0);
decoder.buffer = newSVpvn("", 0);
br_pem_decoder_setdest(&decoder.decoder, pem_callback, &decoder);
break;
}
case BR_PEM_END_OBJ: {
if (decoder.buffer) {
mXPUSHs(decoder.name);
mXPUSHs(decoder.buffer);
decoder.name = NULL;
decoder.buffer = NULL;
}
break;
}
case BR_PEM_ERROR: {
if (decoder.name)
SvREFCNT_dec(decoder.name);
if (decoder.buffer)
SvREFCNT_dec(decoder.buffer);
Perl_croak(aTHX_ "Could not parse PEM");
break;
}
}
}
MODULE = Crypt::Bear PACKAGE = Crypt::Bear::PEM::Decoder PREFIX = br_pem_decoder_
Crypt::Bear::PEM::Decoder br_pem_decoder_new(class, SV* callback)
CODE:
RETVAL = safemalloc(sizeof *RETVAL);
br_pem_decoder_init(&RETVAL->decoder);
RETVAL->callback = SvREFCNT_inc(callback);
RETVAL->name = NULL;
RETVAL->buffer = NULL;
#ifdef MULTIPLICITY
RETVAL->aTHX = aTHX;
#endif
OUTPUT:
RETVAL
void br_pem_decoder_push(Crypt::Bear::PEM::Decoder self, const char* data, size_t length(data))
CODE:
size_t left = STRLEN_length_of_data;
while (left) {
size_t pushed = br_pem_decoder_push(&self->decoder, data, left);
data += pushed;
lib/Crypt/Bear.xs view on Meta::CPAN
if (RETVAL->key_type == BR_KEYTYPE_RSA) {
rsa_private_key_copy(&RETVAL->rsa, br_skey_decoder_get_rsa(&context));
} else if (RETVAL->key_type == BR_KEYTYPE_EC) {
ec_private_key_copy(&RETVAL->ec, br_skey_decoder_get_ec(&context));
}
OUTPUT:
RETVAL
SV* br_x509_private_key_unpack(Crypt::Bear::X509::PrivateKey self)
CODE:
RETVAL = &PL_sv_undef;
if (self->key_type == BR_KEYTYPE_RSA) {
br_rsa_private_key* key = safemalloc(sizeof *key);
rsa_private_key_copy(key, &self->rsa);
RETVAL = make_magic(key, "Crypt::Bear::RSA::PrivateKey", &Crypt__Bear__RSA__PrivateKey_magic);
} else if (self->key_type == BR_KEYTYPE_EC) {
br_ec_private_key* key = safemalloc(sizeof *key);
ec_private_key_copy(key, &self->ec);
RETVAL = make_magic(key, "Crypt::Bear::EC::PrivateKey", &Crypt__Bear__EC__PrivateKey_magic);
}
OUTPUT:
RETVAL
key_kind_type br_x509_private_key_type(Crypt::Bear::X509::PrivateKey self)
CODE:
RETVAL = self->key_type;
OUTPUT:
RETVAL
MODULE = Crypt::Bear PACKAGE = Crypt::Bear::X509::TrustAnchors PREFIX = br_x509_trust_anchors_
Crypt::Bear::X509::TrustAnchors br_x509_trust_anchors_new(class)
CODE:
RETVAL = safemalloc(sizeof *RETVAL);
trust_anchors_init(RETVAL);
OUTPUT:
RETVAL
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))
CODE:
br_x509_trust_anchor anchor = { .flags = is_ca ? BR_X509_TA_CA : 0};
dn_copy(&anchor.dn, &certificate->dn);
x509_key_copy(&anchor.pkey, br_x509_decoder_get_pkey(&certificate->decoder));
trust_anchors_push(self, &anchor);
void br_x509_trust_anchors_merge(Crypt::Bear::X509::TrustAnchors self, Crypt::Bear::X509::TrustAnchors other)
CODE:
for (size_t i = 0; i < other->used; i++) {
const br_x509_trust_anchor* old = other->array + i;
br_x509_trust_anchor anchor = { .flags = old->flags };
dn_copy(&anchor.dn, &old->dn);
x509_key_copy(&anchor.pkey, &old->pkey);
trust_anchors_push(self, &anchor);
}
void br_x509_trust_anchors_names(Crypt::Bear::X509::TrustAnchors self)
PPCODE:
for (size_t i = 0; i < self->used; i++) {
const br_x509_trust_anchor* anchor = self->array + i;
mXPUSHp((const char*)anchor->dn.data, anchor->dn.len);
}
UV br_x509_trust_anchors_count(Crypt::Bear::X509::TrustAnchors self)
CODE:
RETVAL = self->used;
OUTPUT:
RETVAL
MODULE = Crypt::Bear PACKAGE = Crypt::Bear::X509::Validator PREFIX = br_x509_validator_
void start_chain(Crypt::Bear::X509::Validator self, const char* server_name)
CODE:
((*self)->start_chain)(self, server_name);
void start_certificate(Crypt::Bear::X509::Validator self, size_t length)
CODE:
((*self)->start_cert)(self, length);
void append(Crypt::Bear::X509::Validator self, const unsigned char* data, size_t length(data))
CODE:
((*self)->append)(self, data, STRLEN_length_of_data);
void end_certificate(Crypt::Bear::X509::Validator self)
CODE:
((*self)->end_cert)(self);
void end_chain(Crypt::Bear::X509::Validator self)
CODE:
((*self)->end_chain)(self);
SV* get_pkey(Crypt::Bear::X509::Validator self, unsigned wanted_usage)
CODE:
unsigned usage;
const br_x509_pkey* public_key = ((*self)->get_pkey)(self, &usage);
if (wanted_usage && (usage & wanted_usage) != wanted_usage)
RETVAL = &PL_sv_undef;
else if (public_key)
RETVAL = x509_key_unpack(public_key);
else
RETVAL = &PL_sv_undef;
OUTPUT:
RETVAL
MODULE = Crypt::Bear PACKAGE = Crypt::Bear::X509::Validator::Minimal PREFIX = br_x509_minimal_
BOOT:
push_isa(Crypt::Bear::X509::Validator::Minimal, Crypt::Bear::X509::Validator);
Crypt::Bear::X509::Validator::Minimal br_x509_minimal_new(SV* class, Crypt::Bear::X509::TrustAnchors anchors)
CODE:
RETVAL = safemalloc(sizeof *RETVAL);
trust_anchors_copy(&RETVAL->anchors, anchors);
br_x509_minimal_init_full(&RETVAL->context, RETVAL->anchors.array, RETVAL->anchors.used);
OUTPUT:
RETVAL
#if 0
lib/Crypt/Bear.xs view on Meta::CPAN
br_ssl_engine_set_buffer(&RETVAL->context.eng, RETVAL->buffer, sizeof RETVAL->buffer, true);
private_certificate_init(&RETVAL->private);
OUTPUT:
RETVAL
bool br_ssl_client_reset(Crypt::Bear::SSL::Client self, SV* server_name, bool resume_session = FALSE);
CODE:
if (SvOK(server_name))
RETVAL = br_ssl_client_reset(&self->context, SvPV_nolen(server_name), resume_session);
else
RETVAL = br_ssl_client_reset(&self->context, NULL, resume_session);
OUTPUT:
RETVAL
void br_ssl_client_set_client_certificate(Crypt::Bear::SSL::Client self, Crypt::Bear::SSL::PrivateCertificate priv_cert)
CODE:
private_certificate_copy(&self->private, priv_cert);
if (priv_cert->key.key_type == BR_KEYTYPE_RSA) {
br_ssl_client_set_single_rsa(&self->context, self->private.chain.array, self->private.chain.used, &self->private.key.rsa, rsa_pkcs1_sign);
} else if (priv_cert->key.key_type == BR_KEYTYPE_EC) {
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);
} else {
Perl_croak(aTHX_ "Invalid private key");
}
void br_ssl_client_forget_session(Crypt::Bear::SSL::Client self)
CODE:
br_ssl_client_forget_session(&self->context);
MODULE = Crypt::Bear PACKAGE = Crypt::Bear::SSL::Server PREFIX = br_ssl_server_
BOOT:
push_isa(Crypt::Bear::SSL::Server, Crypt::Bear::SSL::Engine);
Crypt::Bear::SSL::Server br_ssl_server_new(class, Crypt::Bear::SSL::PrivateCertificate priv_cert)
CODE:
RETVAL = safemalloc(sizeof *RETVAL);
private_certificate_copy(&RETVAL->private, priv_cert);
if (priv_cert->key.key_type == BR_KEYTYPE_RSA) {
br_ssl_server_init_full_rsa(&RETVAL->context, RETVAL->private.chain.array, RETVAL->private.chain.used, &RETVAL->private.key.rsa);
} else if (priv_cert->key.key_type == BR_KEYTYPE_EC) {
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);
} else {
Safefree(RETVAL);
Perl_croak(aTHX_ "Invalid private key");
}
br_ssl_engine_set_buffer(&RETVAL->context.eng, RETVAL->buffer, BR_SSL_BUFSIZE_BIDI, true);
unsigned error = br_ssl_engine_last_error(&RETVAL->context.eng);
if (error) {
Safefree(RETVAL);
Perl_croak(aTHX_ "Could not instantiate server: %s", lookup_error(error));
}
OUTPUT:
RETVAL
void br_ssl_server_get_client_suites(Crypt::Bear::SSL::Server self)
PPCODE:
size_t len;
const br_suite_translated* suites = br_ssl_server_get_client_suites(&self->context, &len);
for (size_t i = 0; i < len; i++) {
AV* pair = newAV();
av_push(pair, newSVuv(suites[i][0]));
av_push(pair, newSVuv(suites[i][1]));
mXPUSHs(newRV_noinc((SV*)pair));
}
bool br_ssl_server_reset(Crypt::Bear::SSL::Server self);
CODE:
RETVAL = br_ssl_server_reset(&self->context);
OUTPUT:
RETVAL
( run in 0.971 second using v1.01-cache-2.11-cpan-71847e10f99 )