diff options
-rw-r--r-- | doc/luaossl.tex | 4 | ||||
-rw-r--r-- | src/openssl.c | 56 |
2 files changed, 60 insertions, 0 deletions
diff --git a/doc/luaossl.tex b/doc/luaossl.tex index 86f117d..4f06ecf 100644 --- a/doc/luaossl.tex +++ b/doc/luaossl.tex | |||
@@ -768,6 +768,10 @@ Add or interpose a store class method. Returns the previous method, if any. | |||
768 | 768 | ||
769 | Returns a PKCS \#12 binary encoded string. | 769 | Returns a PKCS \#12 binary encoded string. |
770 | 770 | ||
771 | \subsubsection[\fn{pkcs12.parse}]{\fn{pkcs12.parse($bag$[, $passphrase$])}} | ||
772 | |||
773 | Parses a PKCS\#12 bag, presented as a binary string $bag$. The second parameter $passphrase$ is the passphrase required to decrypt the PKCS\#12 bag. The function returns three items; namely the key, certificate and the CA chain, as their respective objects. If an item is absent, it will be substituted with nil. | ||
774 | |||
771 | \end{Module} | 775 | \end{Module} |
772 | 776 | ||
773 | 777 | ||
diff --git a/src/openssl.c b/src/openssl.c index 8fd51d3..5a8e03f 100644 --- a/src/openssl.c +++ b/src/openssl.c | |||
@@ -7434,6 +7434,61 @@ static int p12_interpose(lua_State *L) { | |||
7434 | } /* p12_interpose() */ | 7434 | } /* p12_interpose() */ |
7435 | 7435 | ||
7436 | 7436 | ||
7437 | static int p12_parse(lua_State *L) { | ||
7438 | /* parse a p12 binary string and return the parts */ | ||
7439 | |||
7440 | EVP_PKEY *pkey; | ||
7441 | X509 *cert; | ||
7442 | STACK_OF(X509) *ca = NULL; | ||
7443 | PKCS12 *p12; | ||
7444 | |||
7445 | /* gather input parameters */ | ||
7446 | size_t len; | ||
7447 | const char *blob = luaL_checklstring(L, 1, &len); | ||
7448 | const char *passphrase = luaL_optstring(L, 2, NULL); | ||
7449 | |||
7450 | /* prepare return values */ | ||
7451 | EVP_PKEY **ud_pkey = prepsimple(L, PKEY_CLASS); | ||
7452 | X509 **ud_cert = prepsimple(L, X509_CERT_CLASS); | ||
7453 | STACK_OF(X509) **ud_chain = prepsimple(L, X509_CHAIN_CLASS); | ||
7454 | /* Note: *ud_chain must be initialised to NULL, which prepsimple does. */ | ||
7455 | |||
7456 | /* read PKCS#12 data into OpenSSL memory buffer */ | ||
7457 | BIO *bio = BIO_new_mem_buf((void*)blob, len); | ||
7458 | if (!bio) | ||
7459 | return auxL_error(L, auxL_EOPENSSL, "pkcs12.parse"); | ||
7460 | p12 = d2i_PKCS12_bio(bio, NULL); | ||
7461 | BIO_free(bio); | ||
7462 | if (!p12) | ||
7463 | return auxL_error(L, auxL_EOPENSSL, "pkcs12.parse"); | ||
7464 | |||
7465 | /* the p12 pointer holds the data we're interested in */ | ||
7466 | int rc = PKCS12_parse(p12, passphrase, ud_pkey, ud_cert, ud_chain); | ||
7467 | PKCS12_free(p12); | ||
7468 | if (!rc) | ||
7469 | auxL_error(L, auxL_EOPENSSL, "pkcs12.parse"); | ||
7470 | |||
7471 | /* replace the return values by nil if the ud pointers are NULL */ | ||
7472 | if (*ud_pkey == NULL) { | ||
7473 | lua_pushnil(L); | ||
7474 | lua_replace(L, -4); | ||
7475 | } | ||
7476 | |||
7477 | if (*ud_cert == NULL) { | ||
7478 | lua_pushnil(L); | ||
7479 | lua_replace(L, -3); | ||
7480 | } | ||
7481 | |||
7482 | /* other certificates (a chain, STACK_OF(X509) *) */ | ||
7483 | if (*ud_chain == NULL) { | ||
7484 | lua_pop(L, 1); | ||
7485 | lua_pushnil(L); | ||
7486 | } | ||
7487 | |||
7488 | return 3; | ||
7489 | } /* p12_parse() */ | ||
7490 | |||
7491 | |||
7437 | static int p12__tostring(lua_State *L) { | 7492 | static int p12__tostring(lua_State *L) { |
7438 | PKCS12 *p12 = checksimple(L, 1, PKCS12_CLASS); | 7493 | PKCS12 *p12 = checksimple(L, 1, PKCS12_CLASS); |
7439 | BIO *bio = getbio(L); | 7494 | BIO *bio = getbio(L); |
@@ -7477,6 +7532,7 @@ static const auxL_Reg p12_metatable[] = { | |||
7477 | static const auxL_Reg p12_globals[] = { | 7532 | static const auxL_Reg p12_globals[] = { |
7478 | { "new", &p12_new }, | 7533 | { "new", &p12_new }, |
7479 | { "interpose", &p12_interpose }, | 7534 | { "interpose", &p12_interpose }, |
7535 | { "parse", &p12_parse }, | ||
7480 | { NULL, NULL }, | 7536 | { NULL, NULL }, |
7481 | }; | 7537 | }; |
7482 | 7538 | ||