summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAsh Berlin <ash_github@firemirror.com>2016-04-10 22:15:33 +0100
committerAsh Berlin <ash_github@firemirror.com>2016-04-11 19:32:33 +0100
commit36277465de786618aa94bc2d33c0ffce5e2102a3 (patch)
treef26631dc3b7eca5157b65c5ad33a00a7aa9a8a37
parent85bcdb001a5d65ed32087b23ebd802ddba470088 (diff)
downloadluaossl-36277465de786618aa94bc2d33c0ffce5e2102a3.tar.gz
luaossl-36277465de786618aa94bc2d33c0ffce5e2102a3.tar.bz2
luaossl-36277465de786618aa94bc2d33c0ffce5e2102a3.zip
Support for getting and setting SAN on a CSR
Extensions in a CSR are a bit more complex than in a CRL or a certificate itself so we don't quite use the same interface.
-rw-r--r--doc/luaossl.tex8
-rw-r--r--src/openssl.c81
2 files changed, 89 insertions, 0 deletions
diff --git a/doc/luaossl.tex b/doc/luaossl.tex
index 433dd03..7db7463 100644
--- a/doc/luaossl.tex
+++ b/doc/luaossl.tex
@@ -597,6 +597,14 @@ Returns the subject distinguished name as an \module{x509.name} object.
597 597
598Sets the subject distinguished name. $name$ should be an \module{x509.name} object. 598Sets the subject distinguished name. $name$ should be an \module{x509.name} object.
599 599
600\subsubsection[\fn{csr:getSubjectAlt}]{\fn{csr:getSubjectAlt()}}
601
602Returns the subject alternative name as an \module{x509.altname} object.
603
604\subsubsection[\fn{csr:setSubjectAlt}]{\fn{csr:setSubjectAlt($name$)}}
605
606Sets the subject alternative names. $name$ should be an \module{x509.altname} object.
607
600\subsubsection[\fn{csr:getPublicKey}]{\fn{csr:getPublicKey()}} 608\subsubsection[\fn{csr:getPublicKey}]{\fn{csr:getPublicKey()}}
601 609
602Returns the public key component as an \module{openssl.pkey} object. 610Returns the public key component as an \module{openssl.pkey} object.
diff --git a/src/openssl.c b/src/openssl.c
index 2893d04..f8c5047 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -5488,6 +5488,85 @@ static int xr_setPublicKey(lua_State *L) {
5488} /* xr_setPublicKey() */ 5488} /* xr_setPublicKey() */
5489 5489
5490 5490
5491static int xr_setExtensionByNid(lua_State *L, X509_REQ *csr, int target_nid, void* value) {
5492 STACK_OF(X509_EXTENSION) *sk = NULL;
5493 X509_ATTRIBUTE *attr;
5494 int has_attrs=0, idx, *pnid;
5495
5496 // Replace existing if it's there. Extensions are stored in a CSR in an interesting way:
5497 //
5498 // They are stored as a list under either (most likely) the "official"
5499 // NID_ext_req or under NID_ms_ext_req which means everything is stored
5500 // under a list in a single "attribute" so we can't use X509_REQ_add1_attr
5501 // or similar.
5502 //
5503 // Instead we have to get the extensions, find and replace the SAN if it's
5504 // in there, then *replace* the extensions in the list of attributes. (If
5505 // we just try to add it the old ones are found first and don't take
5506 // priority)
5507
5508 has_attrs = X509_REQ_get_attr_count(csr);
5509 sk = X509_REQ_get_extensions(csr);
5510
5511 if (!X509V3_add1_i2d(&sk, target_nid, value, 0, X509V3_ADD_REPLACE))
5512 goto error;
5513
5514 if (X509_REQ_add_extensions(csr, sk) == 0)
5515 goto error;
5516
5517 // Delete the old extensions attribute, so that the one we just added takes priority
5518 if (has_attrs) {
5519 for (pnid = X509_REQ_get_extension_nids(); *pnid != NID_undef; pnid++) {
5520 idx = X509_REQ_get_attr_by_NID(csr, *pnid, -1);
5521 if (idx == -1)
5522 continue;
5523 if (!(attr = X509_REQ_delete_attr(csr, idx)))
5524 goto error;
5525 X509_ATTRIBUTE_free(attr);
5526 break;
5527 }
5528 if (!attr)
5529 goto error;
5530 }
5531
5532 // We have to mark the encoded form as invalid, otherwise when we write it
5533 // out again it will use the loaded version
5534 csr->req_info->enc.modified = 1;
5535
5536 sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free);
5537 lua_pushboolean(L, 1);
5538 return 1;
5539error:
5540 if (sk)
5541 sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free);
5542 return auxL_error(L, auxL_EOPENSSL, "x509.csr.setExtensionByNid");
5543} /* xr_setExtensionByNid() */
5544
5545
5546static int xr_setSubjectAlt(lua_State *L) {
5547 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
5548 GENERAL_NAMES *gens = checksimple(L, 2, X509_GENS_CLASS);
5549 return xr_setExtensionByNid(L, csr, NID_subject_alt_name, gens);
5550} /* xr_setSubjectAlt */
5551
5552
5553static int xr_getSubjectAlt(lua_State *L) {
5554 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
5555 GENERAL_NAMES *gens;
5556 STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(csr);
5557
5558 gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
5559 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
5560 if (!gens) goto error;
5561
5562 gn_dup(L, gens);
5563 return 1;
5564error:
5565 return 0;
5566} /* xr_getSubjectAlt() */
5567
5568
5569
5491static int xr_sign(lua_State *L) { 5570static int xr_sign(lua_State *L) {
5492 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); 5571 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
5493 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); 5572 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
@@ -5545,6 +5624,8 @@ static const auxL_Reg xr_methods[] = {
5545 { "setSubject", &xr_setSubject }, 5624 { "setSubject", &xr_setSubject },
5546 { "getPublicKey", &xr_getPublicKey }, 5625 { "getPublicKey", &xr_getPublicKey },
5547 { "setPublicKey", &xr_setPublicKey }, 5626 { "setPublicKey", &xr_setPublicKey },
5627 { "getSubjectAlt", &xr_getSubjectAlt },
5628 { "setSubjectAlt", &xr_setSubjectAlt },
5548 { "sign", &xr_sign }, 5629 { "sign", &xr_sign },
5549 { "tostring", &xr__tostring }, 5630 { "tostring", &xr__tostring },
5550 { NULL, NULL }, 5631 { NULL, NULL },