38#include <openssl/asn1.h>
39#include <openssl/asn1t.h>
40#include <openssl/err.h>
41#include <openssl/evp.h>
42#include <openssl/pem.h>
43#include <openssl/rsa.h>
44#include <openssl/x509v3.h>
61 sk_X509_EXTENSION_pop_free(ske, X509_EXTENSION_free);
63using EVP_PKEY_ptr = std::unique_ptr<EVP_PKEY,
decltype(&EVP_PKEY_free)>;
64using X509_ptr = std::unique_ptr<X509,
decltype(&X509_free)>;
65using X509_NAME_ptr = std::unique_ptr<X509_NAME,
decltype(&X509_NAME_free)>;
66using X509_REQ_ptr = std::unique_ptr<X509_REQ,
decltype(&X509_REQ_free)>;
78#define KEY_USAGE_OID "2.5.29.15"
80#define SUBJ_ALT_NAME_OID "2.5.29.17"
88#define XRDGSI_VOMS_ATCAP_OID "1.3.6.1.4.1.8005.100.100.4"
89#define XRDGSI_VOMS_ACSEQ_OID "1.3.6.1.4.1.8005.100.100.5"
91#define BIO_PRINT(b,c) \
93 BIO_get_mem_ptr(b, &bptr); \
95 char *s = new char[bptr->length+1]; \
96 memcpy(s, bptr->data, bptr->length); \
97 s[bptr->length] = '\0'; \
101 PRINT("ERROR: "<<c<<" BIO internal buffer undefined!"); \
105#define BIO_GET_STRING(b,str) \
107 BIO_get_mem_ptr(b, &bptr); \
109 char *s = new char[bptr->length+1]; \
110 memcpy(s, bptr->data, bptr->length); \
111 s[bptr->length] = '\0'; \
115 PRINT("ERROR: GET_STRING: BIO internal buffer undefined!"); \
121 EVP_PKEY_CTX *ckctx = EVP_PKEY_CTX_new(pkey, 0);
122 rc = EVP_PKEY_check(ckctx);
123 EVP_PKEY_CTX_free(ckctx);
138ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION_OLD) =
140 ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION, proxyPolicy, PROXY_POLICY),
141 ASN1_EXP_OPT(PROXY_CERT_INFO_EXTENSION, pcPathLengthConstraint, ASN1_INTEGER, 1)
142} ASN1_SEQUENCE_END_name(PROXY_CERT_INFO_EXTENSION, PROXY_CERT_INFO_EXTENSION_OLD)
144IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(PROXY_CERT_INFO_EXTENSION, PROXY_CERT_INFO_EXTENSION_OLD, PROXY_CERT_INFO_EXTENSION_OLD)
161 X509_EXTENSION *ext = (X509_EXTENSION *)extdata;
165 OBJ_obj2txt(s,
sizeof(s), X509_EXTENSION_get_object(ext), 1);
168 const unsigned char *p = ASN1_STRING_get0_data(X509_EXTENSION_get_data(ext));
169 PROXY_CERT_INFO_EXTENSION *pci = 0;
171 pci = d2i_PROXY_CERT_INFO_EXTENSION(0, &p, ASN1_STRING_length(X509_EXTENSION_get_data(ext)));
173 pci = d2i_PROXY_CERT_INFO_EXTENSION_OLD(0, &p, ASN1_STRING_length(X509_EXTENSION_get_data(ext)));
180 if (pci->pcPathLengthConstraint) {
181 pathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint);
186 *haspolicy = (pci->proxyPolicy) ? 1 : 0;
204 X509_EXTENSION *ext = (X509_EXTENSION *)extdata;
208 OBJ_obj2txt(s,
sizeof(s), X509_EXTENSION_get_object(ext), 1);
211 const unsigned char *p = ASN1_STRING_get0_data(X509_EXTENSION_get_data(ext));
212 PROXY_CERT_INFO_EXTENSION *pci = 0;
214 pci = d2i_PROXY_CERT_INFO_EXTENSION(0, &p, ASN1_STRING_length(X509_EXTENSION_get_data(ext)));
216 pci = d2i_PROXY_CERT_INFO_EXTENSION_OLD(0, &p, ASN1_STRING_length(X509_EXTENSION_get_data(ext)));
221 if (pci->pcPathLengthConstraint) {
222 ASN1_INTEGER_set(pci->pcPathLengthConstraint, pathlen);
246 EPNAME(
"X509CreateProxy");
249 if (!fnc || !fnk || !xp || !kp) {
250 PRINT(
"invalid inputs ");
256 OpenSSL_add_all_ciphers();
257 OpenSSL_add_all_digests();
258 ERR_load_crypto_strings();
262 int valid = (pxopt) ? pxopt->
valid : 43200;
263 int depthlen = (pxopt) ? pxopt->
depthlen : -1;
268 FILE *fc =
fopen(fnc,
"r");
271 if (PEM_read_X509(fc, &xEEC, 0, 0)) {
272 DEBUG(
"EEC certificate loaded from file: "<<fnc);
274 PRINT(
"unable to load EEC certificate from file: "<<fnc);
279 PRINT(
"EEC certificate cannot be opened (file: "<<fnc<<
")");
284 int now = (int)time(0);
286 PRINT(
"EEC certificate has expired");
294 FILE *fk =
fopen(fnk,
"r");
299 PRINT(
"Your identity: "<<sbj);
300 if ((PEM_read_PrivateKey(fk, &ekEEC, 0, 0))) {
301 DEBUG(
"EEC private key loaded from file: "<<fnk);
303 PRINT(
"unable to load EEC private key from file: "<<fnk);
309 PRINT(
"EEC private key file cannot be opened (file: "<<fnk<<
")");
316 PRINT(
"inconsistent key loaded");
317 EVP_PKEY_free(ekEEC);
323 X509_REQ *preq = X509_REQ_new();
325 PRINT(
"cannot to create cert request");
326 EVP_PKEY_free(ekEEC);
332 BIGNUM *e = BN_new();
334 PRINT(
"proxy key could not be generated - return");
335 EVP_PKEY_free(ekEEC);
339 BN_set_word(e, 0x10001);
341 EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, 0);
342 EVP_PKEY_keygen_init(pkctx);
343 EVP_PKEY_CTX_set_rsa_keygen_bits(pkctx, bits);
344#if OPENSSL_VERSION_NUMBER >= 0x30000000L
345 EVP_PKEY_CTX_set1_rsa_keygen_pubexp(pkctx, e);
348 EVP_PKEY_CTX_set_rsa_keygen_pubexp(pkctx, e);
350 EVP_PKEY_keygen(pkctx, &ekPX);
351 EVP_PKEY_CTX_free(pkctx);
353 PRINT(
"proxy key could not be generated - return");
354 EVP_PKEY_free(ekEEC);
358 X509_REQ_set_pubkey(preq, ekPX);
368 X509_NAME *psubj = X509_NAME_dup(X509_get_subject_name(xEEC));
370 unsigned char sn[20] = {0};
371 sprintf((
char *)sn,
"%d", serial);
372 if (!X509_NAME_add_entry_by_txt(psubj, (
char *)
"CN", MBSTRING_ASC,
374 PRINT(
"could not add CN - (serial: "<<serial<<
", sn: "<<sn<<
")");
379 if (X509_REQ_set_subject_name(preq, psubj) != 1) {
380 PRINT(
"could not set subject name - return");
386 PROXY_CERT_INFO_EXTENSION *pci = PROXY_CERT_INFO_EXTENSION_new();
388 PRINT(
"could not create structure for extension - return");
391 pci->proxyPolicy->policyLanguage = OBJ_txt2obj(
"1.3.6.1.5.5.7.21.1", 1);
395 if ((pci->pcPathLengthConstraint = ASN1_INTEGER_new())) {
396 ASN1_INTEGER_set(pci->pcPathLengthConstraint, depthlen);
398 PRINT(
"could not set the path length contrain");
405 X509_EXTENSION *ext = X509_EXTENSION_new();
407 PRINT(
"could not create extension object");
412 if (!obj || X509_EXTENSION_set_object(ext, obj) != 1) {
413 PRINT(
"could not set extension name");
417 if (X509_EXTENSION_set_critical(ext, 1) != 1) {
418 PRINT(
"could not set extension critical flag");
422 int len = i2d_PROXY_CERT_INFO_EXTENSION(pci, 0);
423 unsigned char *data = (
unsigned char *) malloc(len);
425 PRINT(
"could not allocate data field for extension");
428 unsigned char *pp = data;
429 if ((i2d_PROXY_CERT_INFO_EXTENSION(pci, &pp)) <= 0) {
430 PRINT(
"problem converting data for extension");
434 ASN1_OCTET_STRING *os = ASN1_OCTET_STRING_new();
436 PRINT(
"could not allocate data field for extension");
440 if (ASN1_OCTET_STRING_set(os, data, len) == 0) {
441 PRINT(
"could not allocate data field for extension");
442 ASN1_STRING_free(os);
447 if (X509_EXTENSION_set_data(ext, os) == 0) {
448 PRINT(
"could not allocate data field for extension");
449 ASN1_STRING_free(os);
452 ASN1_STRING_free(os);
454 STACK_OF(X509_EXTENSION) *esk = sk_X509_EXTENSION_new_null();
456 PRINT(
"could not create stack for extensions");
461 if (sk_X509_EXTENSION_push(esk, ext) == 0) {
462 PRINT(
"could not push the extension in the stack");
466 if (!(X509_REQ_add_extensions(preq, esk))) {
467 PRINT(
"problem adding extension");
472 if (!(X509_REQ_sign(preq, ekPX, EVP_sha256()))) {
473 PRINT(
"problems signing the request");
478 X509 *xPX = X509_new();
480 PRINT(
"could not create certificate object for proxies");
485 if (X509_set_version(xPX, 2L) != 1) {
486 PRINT(
"could not set version");
491 if (ASN1_INTEGER_set(X509_get_serialNumber(xPX), serial) != 1) {
492 PRINT(
"could not set serial number");
497 if (X509_set_subject_name(xPX, psubj) != 1) {
498 PRINT(
"could not set subject name");
501 X509_NAME_free(psubj);
504 if (X509_set_issuer_name(xPX, X509_get_subject_name(xEEC)) != 1) {
505 PRINT(
"could not set issuer name");
510 if (X509_set_pubkey(xPX, ekPX) != 1) {
511 PRINT(
"could not set issuer name");
516 if (!X509_gmtime_adj(X509_get_notBefore(xPX), 0)) {
517 PRINT(
"could not set notBefore");
522 if (!X509_gmtime_adj(X509_get_notAfter(xPX), valid)) {
523 PRINT(
"could not set notAfter");
528#if OPENSSL_VERSION_NUMBER < 0x40000000L
529 X509_EXTENSION *xEECext = 0;
531 const X509_EXTENSION *xEECext = 0;
533 int nEECext = X509_get_ext_count(xEEC);
534 DEBUG(
"number of extensions found in the original certificate: "<< nEECext);
536 bool haskeyusage = 0;
537 for (i = 0; i< nEECext; i++) {
538 xEECext = X509_get_ext(xEEC, i);
540 OBJ_obj2txt(s,
sizeof(s), X509_EXTENSION_get_object(xEECext), 1);
542 if (!haskeyusage && !strcmp(s,
KEY_USAGE_OID)) haskeyusage = 1;
546 X509_EXTENSION *xEECextdup = X509_EXTENSION_dup(xEECext);
547 if (X509_add_ext(xPX, xEECextdup, -1) == 0) {
548 PRINT(
"could not push the extension '"<<s<<
"' in the stack");
552 int crit = X509_EXTENSION_get_critical(xEECextdup);
553 DEBUG(
"added extension '"<<s<<
"', critical: " << crit);
558 PRINT(
">>> WARNING: critical extension 'Key Usage' not found in original certificate! ");
559 PRINT(
">>> WARNING: this proxy may not be accepted by some parsers. ");
563 if (X509_add_ext(xPX, ext, -1) != 1) {
564 PRINT(
"could not add extension");
570 if (!(X509_sign(xPX, ekEEC, EVP_sha256()))) {
571 PRINT(
"problems signing the certificate");
578 PRINT(
"could not create container for proxy certificate");
586 PRINT(
"could not create container for EEC certificate");
592 PRINT(
"could not creatr out PKI");
601 FILE *fp =
fopen(fnp,
"w");
604 PRINT(
"cannot open file to save the proxy certificate (file: "<<fnp<<
")");
607 else if ( (ifp = fileno(fp)) == -1) {
608 PRINT(
"got invalid file descriptor for the proxy certificate (file: "<<
614 else if (fchmod(ifp, 0600) == -1) {
615 PRINT(
"cannot set permissions on file: "<<fnp<<
" (errno: "<<errno<<
")");
619 else if (!rc && PEM_write_X509(fp, xPX) != 1) {
620 PRINT(
"error while writing proxy certificate");
624 else if (!rc && PEM_write_PrivateKey(fp, ekPX, 0, 0, 0, 0, 0) != 1) {
625 PRINT(
"error while writing proxy private key");
629 else if (!rc && PEM_write_X509(fp, xEEC) != 1) {
630 PRINT(
"error while writing EEC certificate");
640 EVP_PKEY_free(ekEEC);
642 sk_X509_EXTENSION_free(esk);
657 EPNAME(
"X509CreateProxyReq");
660 if (!xcpi || !(xcpi->
Opaque())) {
661 PRINT(
"input proxy certificate not specified");
666 X509 *xpi = (X509 *)(xcpi->
Opaque());
670 PRINT(
"EEC certificate has expired");
686 xro.reset(X509_REQ_new());
688 PRINT(
"cannot to create cert request");
694 ekro.reset(X509_get_pubkey(xpi));
695 int bits = EVP_PKEY_bits(ekro.get());
701 BIGNUM *e = BN_new();
703 PRINT(
"proxy key could not be generated - return");
706 BN_set_word(e, 0x10001);
707 EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, 0);
708 EVP_PKEY_keygen_init(pkctx);
709 EVP_PKEY_CTX_set_rsa_keygen_bits(pkctx, bits);
710#if OPENSSL_VERSION_NUMBER >= 0x30000000L
711 EVP_PKEY_CTX_set1_rsa_keygen_pubexp(pkctx, e);
714 EVP_PKEY_CTX_set_rsa_keygen_pubexp(pkctx, e);
717 EVP_PKEY *tmppk =
nullptr;
718 EVP_PKEY_keygen(pkctx, &tmppk);
721 EVP_PKEY_CTX_free(pkctx);
725 PRINT(
"proxy key could not be generated - return");
728 X509_REQ_set_pubkey(xro.get(), ekro.get());
738 psubj.reset(X509_NAME_dup(X509_get_subject_name(xpi)));
739 if (xcro && *xcro && *((
int *)(*xcro)) <= 10100) {
741 int ne = X509_NAME_entry_count(psubj.get());
743 X509_NAME_ENTRY *cne = X509_NAME_delete_entry(psubj.get(), ne-1);
745 X509_NAME_ENTRY_free(cne);
747 DEBUG(
"problems modifying subject name");
753 unsigned char sn[20] = {0};
754 sprintf((
char *)sn,
"%d", serial);
755 if (!X509_NAME_add_entry_by_txt(psubj.get(), (
char *)
"CN", MBSTRING_ASC,
757 PRINT(
"could not add CN - (serial: "<<serial<<
", sn: "<<sn<<
")");
762 if (X509_REQ_set_subject_name(xro.get(), psubj.get()) != 1) {
763 PRINT(
"could not set subject name - return");
769 pci.reset(PROXY_CERT_INFO_EXTENSION_new());
771 PRINT(
"could not create structure for extension - return");
774 pci->proxyPolicy->policyLanguage = OBJ_txt2obj(
"1.3.6.1.5.5.7.21.1", 1);
777 esk.reset(sk_X509_EXTENSION_new_null());
779 PRINT(
"could not create stack for extensions");
784#if OPENSSL_VERSION_NUMBER < 0x40000000L
785 X509_EXTENSION *xpiext = 0;
787 const X509_EXTENSION *xpiext = 0;
789 int npiext = X509_get_ext_count(xpi);
791 bool haskeyusage = 0;
793 for (i = 0; i< npiext; i++) {
794 xpiext = X509_get_ext(xpi, i);
796 OBJ_obj2txt(s,
sizeof(s), X509_EXTENSION_get_object(xpiext), 1);
798 if (!haskeyusage && !strcmp(s,
KEY_USAGE_OID)) haskeyusage = 1;
804 const unsigned char *p = ASN1_STRING_get0_data(X509_EXTENSION_get_data(xpiext));
805 PROXY_CERT_INFO_EXTENSION *inpci = 0;
807 inpci = d2i_PROXY_CERT_INFO_EXTENSION(0, &p, ASN1_STRING_length(X509_EXTENSION_get_data(xpiext)));
809 inpci = d2i_PROXY_CERT_INFO_EXTENSION_OLD(0, &p, ASN1_STRING_length(X509_EXTENSION_get_data(xpiext)));
811 inpci->pcPathLengthConstraint)
812 indepthlen = ASN1_INTEGER_get(inpci->pcPathLengthConstraint);
813 DEBUG(
"IN depth length: "<<indepthlen);
814 PROXY_CERT_INFO_EXTENSION_free(inpci);
817 X509_EXTENSION *xpiextdup = X509_EXTENSION_dup(xpiext);
818 if (sk_X509_EXTENSION_push(esk.get(), xpiextdup) == 0) {
819 PRINT(
"could not push the extension '"<<s<<
"' in the stack");
820 X509_EXTENSION_free(xpiextdup);
824 int crit = X509_EXTENSION_get_critical(xpiextdup);
825 DEBUG(
"added extension '"<<s<<
"', critical: " << crit);
833 PRINT(
">>> WARNING: critical extension 'Key Usage' not found in original certificate! ");
834 PRINT(
">>> WARNING: this proxy may not be accepted by some parsers. ");
838 if (indepthlen > -1) {
839 if ((pci->pcPathLengthConstraint = ASN1_INTEGER_new())) {
840 int depthlen = (indepthlen > 0) ? (indepthlen-1) : 0;
841 ASN1_INTEGER_set(pci->pcPathLengthConstraint, depthlen);
843 PRINT(
"could not set the path length contrain");
849 ext.reset(X509_EXTENSION_new());
851 PRINT(
"could not create extension object");
855 int len = i2d_PROXY_CERT_INFO_EXTENSION(pci.get(), 0);
856 unsigned char *data = (
unsigned char *) malloc(len);
858 PRINT(
"could not allocate data field for extension");
861 unsigned char *pp = data;
862 if ((i2d_PROXY_CERT_INFO_EXTENSION(pci.get(), &pp)) <= 0) {
863 PRINT(
"problem converting data for extension");
867 ASN1_OCTET_STRING *os = ASN1_OCTET_STRING_new();
869 PRINT(
"could not allocate data field for extension");
873 if (ASN1_OCTET_STRING_set(os, data, len) == 0) {
874 PRINT(
"could not allocate data field for extension");
875 ASN1_STRING_free(os);
880 if (X509_EXTENSION_set_data(ext.get(), os) == 0) {
881 PRINT(
"could not allocate data field for extension");
882 ASN1_STRING_free(os);
885 ASN1_STRING_free(os);
890 if (!obj || X509_EXTENSION_set_object(ext.get(), obj) != 1) {
891 PRINT(
"could not set extension name");
892 ASN1_OBJECT_free(obj);
895 ASN1_OBJECT_free(obj);
899 if (X509_EXTENSION_set_critical(ext.get(), 1) != 1) {
900 PRINT(
"could not set extension critical flag");
903 if (sk_X509_EXTENSION_push(esk.get(), ext.get()) == 0) {
904 PRINT(
"could not push the extension in the stack");
911 if (!(X509_REQ_add_extensions(xro.get(), esk.get()))) {
912 PRINT(
"problem adding extension");
917 if (!(X509_REQ_sign(xro.get(), ekro.get(), EVP_sha256()))) {
918 PRINT(
"problems signing the request");
941 EPNAME(
"X509SignProxyReq");
944 if (!xcpi || !kcpi || !xcri || !xcpo) {
945 PRINT(
"invalid inputs");
950 int timeleft = xcpi->
NotAfter() - (int)time(0);
952 PRINT(
"EEC certificate has expired");
956 X509 *xpi = (X509 *)(xcpi->
Opaque());
960 PRINT(
"inconsistent key loaded");
974#if OPENSSL_VERSION_NUMBER >= 0x30000000L
975 ekpi.reset(EVP_PKEY_dup((EVP_PKEY *)(kcpi->
Opaque())));
977 PRINT(
"could not create a EVP_PKEY * instance - return");
981 RSA *kpi = EVP_PKEY_get0_RSA((EVP_PKEY *)(kcpi->
Opaque()));
984 ekpi.reset(EVP_PKEY_new());
986 PRINT(
"could not create a EVP_PKEY * instance - return");
989 EVP_PKEY_set1_RSA(ekpi.get(), kpi);
993 X509_REQ *xri = (X509_REQ *)(xcri->
Opaque());
1000 PRINT(
"names undefined");
1008 if (neecr.length() <= 0 || neecr.length() <= 0 || neecp != neecr) {
1009 if (xcri->
Version() <= 10100) {
1011 neecp.erase(psbj.
rfind(
"/CN="));
1012 if (neecr.length() <= 0 || neecr.length() <= 0 || neecp != neecr) {
1013 PRINT(
"Request subject not in the form '<EEC subject> + /CN=<serial>'");
1015 PRINT(
" Proxy: "<<neecp);
1016 PRINT(
" SubRq: "<<neecr);
1020 PRINT(
"Request subject not in the form '<issuer subject> + /CN=<serial>'");
1022 PRINT(
" Proxy: "<<neecp);
1023 PRINT(
" SubRq: "<<neecr);
1030 unsigned int serial = (
unsigned int)(strtol(sserial.c_str(), 0, 10));
1033 xpo.reset(X509_new());
1035 PRINT(
"could not create certificate object for proxies");
1040 if (X509_set_version(xpo.get(), 2L) != 1) {
1041 PRINT(
"could not set version");
1046 if (ASN1_INTEGER_set(X509_get_serialNumber(xpo.get()), serial) != 1) {
1047 PRINT(
"could not set serial number");
1052 if (X509_set_subject_name(xpo.get(), X509_REQ_get_subject_name(xri)) != 1) {
1053 PRINT(
"could not set subject name");
1058 if (X509_set_issuer_name(xpo.get(), X509_get_subject_name(xpi)) != 1) {
1059 PRINT(
"could not set issuer name");
1064 if (X509_set_pubkey(xpo.get(), X509_REQ_get_pubkey(xri)) != 1) {
1065 PRINT(
"could not set public key");
1070 if (!X509_gmtime_adj(X509_get_notBefore(xpo.get()), 0)) {
1071 PRINT(
"could not set notBefore");
1076 if (!X509_gmtime_adj(X509_get_notAfter(xpo.get()), timeleft)) {
1077 PRINT(
"could not set notAfter");
1083#if OPENSSL_VERSION_NUMBER < 0x40000000L
1084 X509_EXTENSION *xpiext = 0, *xriext = 0;
1086 const X509_EXTENSION *xpiext = 0, *xriext = 0;
1088 int npiext = X509_get_ext_count(xpi);
1090 bool haskeyusage = 0;
1091 int indepthlen = -1;
1092 for (i = 0; i< npiext; i++) {
1093 xpiext = X509_get_ext(xpi, i);
1095 const ASN1_OBJECT *obj = X509_EXTENSION_get_object(xpiext);
1097 OBJ_obj2txt(s,
sizeof(s), obj, 1);
1100 const unsigned char *p = ASN1_STRING_get0_data(X509_EXTENSION_get_data(xpiext));
1101 PROXY_CERT_INFO_EXTENSION *inpci = 0;
1103 inpci = d2i_PROXY_CERT_INFO_EXTENSION(0, &p, ASN1_STRING_length(X509_EXTENSION_get_data(xpiext)));
1105 inpci = d2i_PROXY_CERT_INFO_EXTENSION_OLD(0, &p, ASN1_STRING_length(X509_EXTENSION_get_data(xpiext)));
1107 inpci->pcPathLengthConstraint)
1108 indepthlen = ASN1_INTEGER_get(inpci->pcPathLengthConstraint);
1109 DEBUG(
"IN depth length: "<<indepthlen);
1110 PROXY_CERT_INFO_EXTENSION_free(inpci);
1113 if (!haskeyusage && !strcmp(s,
KEY_USAGE_OID)) haskeyusage = 1;
1116 PRINT(
"subject alternative name extension not allowed! Skipping request");
1123 PRINT(
"more than one ProxyCertInfo extension! Skipping request");
1129 X509_EXTENSION *xpiextdup = X509_EXTENSION_dup(xpiext);
1130 if (X509_add_ext(xpo.get(), xpiextdup, -1) == 0) {
1131 PRINT(
"could not push the extension '"<<s<<
"' in the stack");
1132 X509_EXTENSION_free( xpiextdup );
1136 int crit = X509_EXTENSION_get_critical(xpiextdup);
1137 DEBUG(
"added extension '"<<s<<
"', critical: " << crit);
1138 X509_EXTENSION_free( xpiextdup );
1146 xrisk.reset(X509_REQ_get_extensions(xri));
1149 int nriext = sk_X509_EXTENSION_num(xrisk.get());
1150 if (nriext == 0 || !haskeyusage) {
1151 PRINT(
"wrong extensions in request: "<< nriext<<
", "<<haskeyusage);
1156 int reqdepthlen = -1;
1158 const unsigned char *p = ASN1_STRING_get0_data(X509_EXTENSION_get_data(xriext));
1159 PROXY_CERT_INFO_EXTENSION *reqpci =
1160 d2i_PROXY_CERT_INFO_EXTENSION(0, &p, ASN1_STRING_length(X509_EXTENSION_get_data(xriext)));
1162 reqpci->pcPathLengthConstraint)
1163 reqdepthlen = ASN1_INTEGER_get(reqpci->pcPathLengthConstraint);
1164 PROXY_CERT_INFO_EXTENSION_free(reqpci);
1166 DEBUG(
"REQ depth length: "<<reqdepthlen);
1169 int outdepthlen = (reqdepthlen < indepthlen) ? reqdepthlen :
1173 pci.reset(PROXY_CERT_INFO_EXTENSION_new());
1175 PRINT(
"could not create structure for extension - return");
1178 pci->proxyPolicy->policyLanguage = OBJ_txt2obj(
"1.3.6.1.5.5.7.21.1", 1);
1181 if (outdepthlen > -1) {
1182 if ((pci->pcPathLengthConstraint = ASN1_INTEGER_new())) {
1183 int depthlen = (outdepthlen > 0) ? (outdepthlen-1) : 0;
1184 ASN1_INTEGER_set(pci->pcPathLengthConstraint, depthlen);
1186 PRINT(
"could not set the path length contrain");
1191 ext.reset(X509_EXTENSION_new());
1193 PRINT(
"could not create extension object");
1197 int len = i2d_PROXY_CERT_INFO_EXTENSION(pci.get(), 0);
1198 unsigned char *data = (
unsigned char *) malloc(len);
1200 PRINT(
"could not allocate data field for extension");
1203 unsigned char *pp = data;
1204 if ((i2d_PROXY_CERT_INFO_EXTENSION(pci.get(), &pp)) <= 0) {
1205 PRINT(
"problem converting data for extension");
1209 ASN1_OCTET_STRING *os = ASN1_OCTET_STRING_new();
1211 PRINT(
"could not allocate data field for extension");
1215 if (ASN1_OCTET_STRING_set(os, data, len) == 0) {
1216 PRINT(
"could not allocate data field for extension");
1217 ASN1_STRING_free(os);
1222 if (X509_EXTENSION_set_data(ext.get(), os) == 0) {
1223 PRINT(
"could not allocate data field for extension");
1224 ASN1_STRING_free(os);
1227 ASN1_STRING_free(os);
1232 if (!obj || X509_EXTENSION_set_object(ext.get(), obj) != 1) {
1233 PRINT(
"could not set extension name");
1234 ASN1_OBJECT_free( obj );
1237 ASN1_OBJECT_free( obj );
1241 if (X509_EXTENSION_set_critical(ext.get(), 1) != 1) {
1242 PRINT(
"could not set extension critical flag");
1247 if (X509_add_ext(xpo.get(), ext.get(), -1) == 0) {
1248 PRINT(
"could not add extension");
1254 if (!(X509_sign(xpo.get(), ekpi.get(), EVP_sha256()))) {
1255 PRINT(
"problems signing the certificate");
1278 EPNAME(
"X509GetVOMSAttr");
1283 PRINT(
"invalid inputs");
1288 X509 *xpi = (X509 *)(xcpi->
Opaque());
1293#if OPENSSL_VERSION_NUMBER < 0x40000000L
1294 X509_EXTENSION *xpiext = 0;
1296 const X509_EXTENSION *xpiext = 0;
1298 int npiext = X509_get_ext_count(xpi);
1300 for (i = 0; i< npiext; i++) {
1301 xpiext = X509_get_ext(xpi, i);
1303 OBJ_obj2txt(s,
sizeof(s), X509_EXTENSION_get_object(xpiext), 1);
1305 DEBUG(
"found extension '"<<s<<
"'");
1309 const unsigned char *pp = ASN1_STRING_get0_data(X509_EXTENSION_get_data(xpiext));
1310 long length = ASN1_STRING_length(X509_EXTENSION_get_data(xpiext));
1312 DEBUG(
"ret: " << ret <<
" - vat: " << vat);
1327 const unsigned char *p,*ep,*tot,*op,*opp;
1329 int tag, xclass, ret = 0;
1332 ASN1_OCTET_STRING *os = 0;
1338 while ((p < tot) && (op < p)) {
1340 j = ASN1_get_object(&p, &len, &tag, &xclass, length);
1345 PRINT(
"ERROR: error in encoding");
1353 if (j & V_ASN1_CONSTRUCTED) {
1356 PRINT(
"ERROR:CONST: length is greater than " <<length);
1360 if ((j == 0x21) && (len == 0)) {
1367 if ((r == 2) || (p >= tot))
1381 if (tag == V_ASN1_OBJECT) {
1383 if (d2i_ASN1_OBJECT(&o, &opp, len+hl)) {
1384 BIO *mem = BIO_new(BIO_s_mem());
1385 i2a_ASN1_OBJECT(mem, o);
1390 DEBUG(
"AOBJ:"<<objstr<<
" (getvat: "<<getvat<<
")");
1392 PRINT(
"ERROR:AOBJ: BAD OBJECT");
1394 }
else if (tag == V_ASN1_OCTET_STRING) {
1395 int i, printable = 1;
1397 os = d2i_ASN1_OCTET_STRING(0, &opp, len + hl);
1398 if (os && ASN1_STRING_length(os) > 0) {
1399 opp = ASN1_STRING_get0_data(os);
1401 for (i=0; i < ASN1_STRING_length(os); i++) {
1402 if (( (opp[i] <
' ') && (opp[i] !=
'\n') &&
1403 (opp[i] !=
'\r') && (opp[i] !=
'\t')) || (opp[i] >
'~')) {
1411 if (vat.
length() > 0) vat +=
",";
1412 vat += (
const char *)opp;
1415 DEBUG(
"OBJS:" << (
const char *)opp <<
" (len: " << ASN1_STRING_length(os) <<
")");
1419 ASN1_OCTET_STRING_free(os);
1425 if ((tag == V_ASN1_EOC) && (xclass == 0)) {
1438 if (o) ASN1_OBJECT_free(o);
1439 if (os) ASN1_OCTET_STRING_free(os);
1441 DEBUG(
"ret: "<<ret<<
" - getvat: "<<getvat);
1454 EPNAME(
"X509CheckProxy3");
1457 X509 *cert = (X509 *)(xcpi->
Opaque());
1460 int numext = X509_get_ext_count(cert);
1462 emsg =
"certificate has got no extensions";
1465 TRACE(ALL,
"certificate has "<<numext<<
" extensions");
1467#if OPENSSL_VERSION_NUMBER < 0x40000000L
1468 X509_EXTENSION *ext = 0;
1470 const X509_EXTENSION *ext = 0;
1472 PROXY_CERT_INFO_EXTENSION *pci = 0;
1473 for (
int i = 0; i < numext; i++) {
1475#if OPENSSL_VERSION_NUMBER < 0x40000000L
1476 X509_EXTENSION *xext = X509_get_ext(cert, i);
1478 const X509_EXTENSION *xext = X509_get_ext(cert, i);
1483 OBJ_obj2txt(s,
sizeof(s), X509_EXTENSION_get_object(xext), 1);
1484 DEBUG(i <<
": got: "<< s);
1489 const unsigned char *p = ASN1_STRING_get0_data(X509_EXTENSION_get_data(ext));
1490 pci = d2i_PROXY_CERT_INFO_EXTENSION(0, &p, ASN1_STRING_length(X509_EXTENSION_get_data(ext)));
1492 PRINT(
"WARNING: multiple proxyCertInfo extensions found: taking the first");
1498 const unsigned char *p = ASN1_STRING_get0_data(X509_EXTENSION_get_data(ext));
1499 pci = d2i_PROXY_CERT_INFO_EXTENSION_OLD(0, &p, ASN1_STRING_length(X509_EXTENSION_get_data(ext)));
1501 PRINT(
"WARNING: multiple proxyCertInfo extensions found: taking the first");
1508 emsg =
"proxyCertInfo extension not found";
1512 emsg =
"proxyCertInfo extension could not be deserialized";
1517 if ((pci->proxyPolicy) == 0) {
1518 emsg =
"could not access policy from proxyCertInfo extension";
1522 if ((pci->proxyPolicy->policyLanguage) == 0) {
1523 emsg =
"could not access policy language from proxyCertInfo extension";
#define XrdCryptoMinRSABits
#define XrdCryptoDefRSABits
#define gsiProxyCertInfo_OID
#define gsiProxyCertInfo_OLD_OID
time_t XrdCryptosslASN1toUTC(const ASN1_TIME *tsn1)
void XrdCryptosslNameOneLine(const X509_NAME *nm, XrdOucString &s)
void XrdCryptosslSetPathLenConstraint(void *ext, int pathlen)
#define kErrPX_BadExtension
int XrdCryptosslX509CheckProxy3(XrdCryptoX509 *, XrdOucString &)
#define kErrPX_SetAttribute
int XrdCryptosslX509SignProxyReq(XrdCryptoX509 *, XrdCryptoRSA *, XrdCryptoX509Req *, XrdCryptoX509 **)
bool XrdCryptosslProxyCertInfo(const void *ext, int &pathlen, bool *haspolicy=0)
#define kErrPX_NoResources
int XrdCryptosslX509CreateProxyReq(XrdCryptoX509 *, XrdCryptoX509Req **, XrdCryptoRSA **)
int XrdCryptosslX509CreateProxy(const char *, const char *, XrdProxyOpt_t *, XrdCryptogsiX509Chain *, XrdCryptoRSA **, const char *)
int XrdCryptosslX509GetVOMSAttr(XrdCryptoX509 *, XrdOucString &)
#define kErrPX_GenerateKey
#define kErrPX_SetPathDepth
#define kErrPX_ExpiredEEC
#define kErrPX_BadEECfile
static int XrdCheckRSA(EVP_PKEY *pkey)
std::unique_ptr< EVP_PKEY, decltype(&EVP_PKEY_free)> EVP_PKEY_ptr
#define BIO_GET_STRING(b, str)
int XrdCryptosslX509FillUnknownExt(const unsigned char **pp, long length)
static void stackOfX509ExtensionDelete(STACK_OF(X509_EXTENSION) *ske)
#define XRDGSI_VOMS_ATCAP_OID
int XrdCryptosslX509Asn1PrintInfo(int tag, int xclass, int constructed, int indent)
int XrdCryptosslX509FillVOMS(const unsigned char **pp, long length, bool &getvat, XrdOucString &vat)
#define XRDGSI_VOMS_ACSEQ_OID
#define SUBJ_ALT_NAME_OID
std::unique_ptr< STACK_OF(X509_EXTENSION), decltype(&stackOfX509ExtensionDelete)> STACK_OF_X509_EXTENSION_ptr
std::unique_ptr< X509, decltype(&X509_free)> X509_ptr
std::unique_ptr< X509_NAME, decltype(&X509_NAME_free)> X509_NAME_ptr
std::unique_ptr< X509_EXTENSION, decltype(&X509_EXTENSION_free)> X509_EXTENSION_ptr
std::unique_ptr< PROXY_CERT_INFO_EXTENSION, decltype(&PROXY_CERT_INFO_EXTENSION_free)> PROXY_CERT_INFO_EXTENSION_ptr
std::unique_ptr< X509_REQ, decltype(&X509_REQ_free)> X509_REQ_ptr
int emsg(int rc, char *msg)
virtual XrdCryptoRSAdata Opaque()
void PushBack(XrdCryptoX509 *c)
virtual XrdCryptoX509Reqdata Opaque()
virtual XrdCryptoX509data Opaque()
virtual bool IsValid(int when=0)
virtual time_t NotAfter()
int rfind(const char c, int start=STR_NPOS)
static unsigned int GetUInt()