Alt-Crypt-OpenSSL-PKCS12-Broadbean

 view release on metacpan or  search on metacpan

PKCS12.xs  view on Meta::CPAN

#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;

PKCS12.xs  view on Meta::CPAN

  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 )