Alt-Crypt-OpenSSL-PKCS12-Broadbean
view release on metacpan or search on metacpan
#define PKCS12_SAFEBAG_get0_safes(o) ((o)->value.safes)
#define PKCS12_SAFEBAG_get0_type(o) (o)->type
#define PKCS8_pkey_get0_attrs(o) ((o)->attributes)
#define PKCS12_SAFEBAG_get0_attrs(o) ((o)->attrib)
#define CONST_PKCS8_PRIV_KEY_INFO PKCS8_PRIV_KEY_INFO
#define CONST_X509_ALGOR X509_ALGOR
#define CONST_X509_SIG X509_SIG
#define CONST_ASN1_TYPE ASN1_TYPE
#define CONST_STACK_OF(o) STACK_OF(o)
#define CONST_X509_NAME X509_NAME
#define CONST_ASN1_INTEGER ASN1_INTEGER
#define CONST_ASN1_OBJECT ASN1_OBJECT
#define CONST_ASN1_OCTET_STRING ASN1_OCTET_STRING
#define CONST_VOID void
#else
#define CONST_PKCS8_PRIV_KEY_INFO const PKCS8_PRIV_KEY_INFO
#define CONST_X509_ALGOR const X509_ALGOR
#define CONST_X509_SIG const X509_SIG
#define CONST_ASN1_TYPE const ASN1_TYPE
#define CONST_STACK_OF(o) const STACK_OF(o)
#define CONST_X509_NAME const X509_NAME
#define CONST_ASN1_INTEGER const ASN1_INTEGER
#define CONST_ASN1_OBJECT const ASN1_OBJECT
#define CONST_ASN1_OCTET_STRING const ASN1_OCTET_STRING
#define CONST_VOID const void
#endif
const EVP_CIPHER *enc;
int dump_certs_pkeys_bags(pTHX_ BIO *out, CONST_STACK_OF(PKCS12_SAFEBAG) *bags,
const char *pass, int passlen, int options,
char *pempass, const EVP_CIPHER *enc, HV* hash);
static int alg_print(pTHX_ BIO *bio, CONST_X509_ALGOR *alg, HV* hash);
void print_attribute(pTHX_ BIO *out, CONST_ASN1_TYPE *av, char **value);
int print_attribs(pTHX_ BIO *out, CONST_STACK_OF(X509_ATTRIBUTE) *attrlst, const char *name, HV *hash);
void hex_prin(BIO *out, unsigned char *buf, int len);
void dump_cert_text(BIO *out, X509 *x);
SV * get_cert_subject_name(pTHX_ X509 *x);
SV * get_cert_issuer_name(pTHX_ X509 *x);
#define CHECK_OPEN_SSL(p_result) if (!(p_result)) croakSSL(__FILE__, __LINE__);
#define PACKAGE_CROAK(p_message) croak("%s", (p_message))
#define CHECK_NEW(p_var, p_size, p_type) \
if (New(0, p_var, p_size, p_type) == NULL) \
{ PACKAGE_CROAK("unable to alloc buffer"); }
/* fake our package name */
typedef PKCS12* Crypt__OpenSSL__PKCS12;
void croakSSL(char* p_file, int p_line) {
const char* errorReason;
/* Just return the top error on the stack */
errorReason = ERR_reason_error_string(ERR_get_error());
ERR_clear_error();
croak("%s:%d: OpenSSL error: %s", p_file, p_line, errorReason);
}
EVP_PKEY* _load_pkey(char* keyString, EVP_PKEY*(*p_loader)(BIO*, EVP_PKEY**, pem_password_cb*, void*)) {
EVP_PKEY* pkey;
BIO* stringBIO;
if (!strncmp(keyString, "----", 4)) {
CHECK_OPEN_SSL(stringBIO = BIO_new_mem_buf(keyString, strlen(keyString)));
} else {
CHECK_OPEN_SSL(stringBIO = BIO_new_file(keyString, "r"));
}
pkey = p_loader(stringBIO, NULL, NULL, NULL);
(void)BIO_set_close(stringBIO, BIO_CLOSE);
BIO_free_all(stringBIO);
CHECK_OPEN_SSL(pkey);
return pkey;
}
STACK_OF(X509)* _load_cert_chain(char* keyString, STACK_OF(X509_INFO)*(*p_loader)(BIO*, STACK_OF(X509_INFO)*, pem_password_cb*, void*)) {
int i;
STACK_OF(X509_INFO) *xis = NULL;
X509_INFO *xi = NULL;
BIO* stringBIO;
STACK_OF(X509) *stack = sk_X509_new_null();
if (!strncmp(keyString, "----", 4)) {
CHECK_OPEN_SSL(stringBIO = BIO_new_mem_buf(keyString, strlen(keyString)));
} else {
CHECK_OPEN_SSL(stringBIO = BIO_new_file(keyString, "r"));
}
xis = p_loader(stringBIO, NULL, NULL, NULL);
for (i = 0; i < sk_X509_INFO_num(xis); i++) {
xi = sk_X509_INFO_value(xis, i);
if (xi->x509 != NULL && stack != NULL) {
CHECK_OPEN_SSL(xi->x509);
if (!sk_X509_push(stack, xi->x509))
goto end;
xi->x509 = NULL;
}
}
end:
sk_X509_INFO_pop_free(xis, X509_INFO_free);
(void)BIO_set_close(stringBIO, BIO_CLOSE);
BIO_free_all(stringBIO);
return stack;
}
static void sv_bio_error(pTHX_ BIO *bio) {
SV* sv = (SV *)BIO_get_callback_arg(bio);
if (sv) sv_free(sv);
BIO_free_all (bio);
}
SV* extractBioString(pTHX_ BIO* p_stringBio)
{
SV* sv;
char *datap;
long datasize = 0;
CHECK_OPEN_SSL(BIO_flush(p_stringBio) == 1);
datasize = BIO_get_mem_data(p_stringBio, &datap);
sv = newSVpv(datap, datasize);
CHECK_OPEN_SSL(BIO_set_close(p_stringBio, BIO_CLOSE) == 1);
BIO_free(p_stringBio);
return sv;
}
static const char *ssl_error(pTHX) {
BIO *bio;
SV *sv;
STRLEN l;
if((hv_store(mac, "salt_length", strlen("salt_length"), INT2PTR(SV*, salt_len), 0)) == NULL)
croak("unable to add salt_length to the hash");
if((hv_store(RETVAL, "mac", strlen("mac"), newRV_inc((SV *) mac), 0)) == NULL)
croak("unable to add MAC to the hash");
dump_certs_keys_p12(aTHX_ bio, pkcs12, pwd, strlen(pwd), INFO, NULL, RETVAL);
SV * end = extractBioString(aTHX_ bio);
if (SvPOK(end)) {
if (SvCUR(end) != 0)
printf("BIO %s\n", SvPVbyte_nolen(end));
warn("bio from info_as_hash should be zero length - report issue");
}
sv_2mortal((SV*)RETVAL);
OUTPUT:
RETVAL
SV*
info(pkcs12, pwd = "")
Crypt::OpenSSL::PKCS12 pkcs12
char *pwd
PREINIT:
BIO *bio;
STACK_OF(PKCS7) *asafes = NULL;
CONST_ASN1_INTEGER *tmaciter;
#if OPENSSL_VERSION_NUMBER > 0x10100000L
CONST_X509_ALGOR *macalgid;
CONST_ASN1_OBJECT *macobj;
CONST_ASN1_OCTET_STRING *tmac;
CONST_ASN1_OCTET_STRING *tsalt;
#endif
CODE:
CHECK_OPEN_SSL(bio = BIO_new(BIO_s_mem()));
if ((asafes = PKCS12_unpack_authsafes(pkcs12)) == NULL)
RETVAL = newSVpvn("",0);
#if OPENSSL_VERSION_NUMBER > 0x10100000L
PKCS12_get0_mac(&tmac, &macalgid, &tsalt, &tmaciter, pkcs12);
/* current hash algorithms do not use parameters so extract just name,
in future alg_print() may be needed */
X509_ALGOR_get0(&macobj, NULL, NULL, macalgid);
BIO_puts(bio, "MAC: ");
i2a_ASN1_OBJECT(bio, macobj);
/* current hash algorithms do not use parameters so extract just name,
in future alg_print() may be needed */
BIO_printf(bio, ", Iteration %ld\n",
tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L);
BIO_printf(bio, "MAC length: %ld, salt length: %ld\n",
tmac != NULL ? ASN1_STRING_length(tmac) : 0L,
tsalt != NULL ? ASN1_STRING_length(tsalt) : 0L);
#else
tmaciter = pkcs12->mac->iter;
BIO_printf(bio, "MAC Iteration %ld\n",
tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L);
/* If we enter empty password try no password first */
if (!PKCS12_verify_mac(pkcs12, pwd, -1)) {
BIO_printf(bio, "Mac verify error: invalid password?\n");
ERR_print_errors(bio);
goto end;
}
BIO_printf(bio, "MAC verified OK\n");
end:
#endif
dump_certs_keys_p12(aTHX_ bio, pkcs12, pwd, strlen(pwd), INFO, NULL, NULL);
RETVAL = extractBioString(aTHX_ bio);
OUTPUT:
RETVAL
( run in 1.776 second using v1.01-cache-2.11-cpan-39bf76dae61 )