37 #include <sys/types.h>
46 #include <openssl/pem.h>
87 klen = (klen <= 0) ? 24 : klen;
90 char *realsalt = (
char *)salt;
95 char *ibeg = (
char *)memchr(salt+1,
'$',slen-1);
98 int newit = strtol(ibeg+1, &del, 10);
99 if (newit > 0 && del[0] ==
'$' && errno != ERANGE) {
103 realslen = slen - (int)(realsalt-salt);
107 PKCS5_PBKDF2_HMAC_SHA1(pass, plen,
108 (
unsigned char *)realsalt, realslen, it,
109 klen, (
unsigned char *)key);
119 X509 *c = cert ? (X509 *)(cert->
Opaque()) : 0;
120 X509 *r = ref ? (X509 *)(ref->
Opaque()) : 0;
121 EVP_PKEY *rk = r ? X509_get_pubkey(r) : 0;
122 if (!c || !rk)
return 0;
125 return (X509_verify(c, rk) > 0);
135 if (!chain || chain->
Size() <= 1)
139 X509_STORE *store = X509_STORE_new();
144 X509_STORE_set_verify_cb_func(store, 0);
150 X509_STORE_add_cert(store, (X509 *)(cert->
Opaque()));
153 STACK_OF(X509) *stk = sk_X509_new_null();
159 while ((cert = chain->
Next()) && cert->
Opaque()) {
161 cref = (X509 *)(cert->
Opaque());
162 sk_X509_push(stk, (X509 *)(cert->
Opaque()));
166 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
167 if (sk_X509_num(stk) != chain->
Size() - 1)
169 if (sk_num(stk) != chain->
Size() - 1)
174 X509_STORE_CTX *ctx = X509_STORE_CTX_new();
179 X509_STORE_CTX_init(ctx, store, cref, stk);
182 bool verify_ok = (X509_verify_cert(ctx) == 1);
190 X509_STORE_CTX_free(ctx);
191 sk_X509_pop_free(stk, X509_free);
192 X509_STORE_free(store);
202 EPNAME(
"X509ExportChain");
206 if (!chain || chain->
Size() <= 0) {
207 DEBUG(
"chain undefined or empty: nothing to export");
214 DEBUG(
"chain contains only a CA certificate: nothing to export");
219 BIO *bmem = BIO_new(BIO_s_mem());
221 DEBUG(
"unable to create BIO for memory operations");
230 if (!PEM_write_bio_X509(bmem, (X509 *)c->
Opaque())) {
231 DEBUG(
"error while writing proxy certificate");
236 if (withprivatekey) {
239 if (!PEM_write_bio_PrivateKey(bmem, (EVP_PKEY *)(k->
Opaque()),
241 DEBUG(
"error while writing proxy private key");
250 DEBUG(
"Encountered CA in chain; breaking. Subject: " << c->
Subject());
255 if (!PEM_write_bio_X509(bmem, (X509 *)c->
Opaque())) {
256 DEBUG(
"error while writing proxy certificate");
261 DEBUG(
"Encountered self-signed CA in chain; breaking. Subject: " << c->
Subject());
268 int blen = BIO_get_mem_data(bmem, &bdata);
269 DEBUG(
"BIO data: "<<blen<<
" bytes at 0x"<<(
int *)bdata);
276 DEBUG(
"result of serialization: "<<bck->
size<<
" bytes");
278 DEBUG(
"unable to create bucket for serialized format");
294 EPNAME(
"X509ChainToFile");
297 if (!x509 || !file) {
298 DEBUG(
"Invalid inputs");
302 if (PEM_write_X509(file, (X509 *)x509->
Opaque()) != 1) {
303 DEBUG(
"error while writing certificate " << fname);
314 EPNAME(
"X509ChainToFile");
318 DEBUG(
"Invalid inputs");
323 FILE *fp =
fopen(fn,
"w");
325 DEBUG(
"cannot open file to save chain (file: "<<fn<<
")");
328 int ifp = fileno(fp);
330 DEBUG(
"got invalid file descriptor (file: "<<fn<<
")");
340 DEBUG(
"could not lock file: "<<fn<<
")");
346 if (fchmod(ifp, 0600) == -1) {
347 DEBUG(
"cannot set permissions on file: "<<fn<<
" (errno: "<<errno<<
")");
357 if (PEM_write_X509(fp, (X509 *)c->
Opaque()) != 1) {
358 DEBUG(
"error while writing proxy certificate");
365 if (PEM_write_PrivateKey(fp, (EVP_PKEY *)(k->
Opaque()),
366 0, 0, 0, 0, 0) != 1) {
367 DEBUG(
"error while writing proxy private key");
375 if (PEM_write_X509(fp, (X509 *)c->
Opaque()) != 1) {
376 DEBUG(
"error while writing proxy certificate");
397 DEBUG(
"chain undefined: can do nothing");
414 STACK_OF(X509) *pChain = pc->getChain();
416 for (
int i=0; i < sk_X509_num(pChain); i++) {
417 X509 *cert = sk_X509_value(pChain, i);
425 #if OPENSSL_VERSION_NUMBER < 0x010100000L
426 CRYPTO_add(&(cert->references), 1, CRYPTO_LOCK_X509);
433 DEBUG(
"could not create certificate: memory exhausted?");
452 FILE *fcer =
fopen(fname,
"r");
454 DEBUG(
"unable to open file (errno: "<<errno<<
")");
466 const char *fname,
const char *fkey)
477 DEBUG(
"FILE object undefined: can do nothing");
483 DEBUG(
"chain undefined: can do nothing");
489 while (PEM_read_X509(fcer, &xcer, 0, 0)) {
495 DEBUG(
"certificate for '"<<c->
Subject()<<
"'added to the chain - ord: "<<chain->
Size());
497 DEBUG(
"could not create certificate: memory exhausted?");
515 fcer =
fopen(fkey,
"r");
517 DEBUG(
"unable to open key file (errno: "<<errno<<
")");
523 if (!PEM_read_PrivateKey(fcer, &rsa, 0, 0)) {
524 DEBUG(
"no RSA private key found in file " << fname);
526 DEBUG(
"found a RSA private key in file " << fname);
532 while (cert && cert->
Opaque()) {
535 EVP_PKEY *evpp = X509_get_pubkey((X509 *)(cert->
Opaque()));
538 #if OPENSSL_VERSION_NUMBER < 0x30000000L
539 int rc = EVP_PKEY_cmp(evpp, rsa);
541 int rc = EVP_PKEY_eq(evpp, rsa);
548 DEBUG(
"RSA key completed");
555 cert = chain->
Next();
579 EPNAME(
"X509ParseBucket");
583 if (!b || b->
size <= 0) {
584 DEBUG(
"bucket undefined or empty: can do nothing");
590 DEBUG(
"chain undefined: can do nothing");
595 BIO *bmem = BIO_new(BIO_s_mem());
597 DEBUG(
"unable to create BIO to import certificates");
602 if (BIO_write(bmem,(
const void *)(b->
buffer),b->
size) != b->
size) {
603 DEBUG(
"problems writing data to BIO");
610 while (PEM_read_bio_X509(bmem, &xcer, 0, 0)) {
617 DEBUG(
"certificate added to the chain - ord: "<<chain->
Size());
619 DEBUG(
"could not create certificate: memory exhausted?");
631 if (nci && BIO_write(bmem,(
const void *)(b->
buffer),b->
size) == b->
size) {
633 if (!PEM_read_bio_PrivateKey(bmem, &rsa, 0, 0)) {
634 DEBUG(
"no RSA private key found in bucket");
636 DEBUG(
"found a RSA private key in bucket");
642 while (cert && cert->
Opaque()) {
645 EVP_PKEY *evpp = X509_get_pubkey((X509 *)(cert->
Opaque()));
648 #if OPENSSL_VERSION_NUMBER < 0x30000000L
649 int rc = EVP_PKEY_cmp(evpp, rsa);
651 int rc = EVP_PKEY_eq(evpp, rsa);
658 DEBUG(
"RSA key completed");
665 cert = chain->
Next();
693 if (!tsn1)
return etime;
702 if ((sscanf((
const char *)(tsn1->data),
703 "%02d%02d%02d%02d%02d%02d%c",
704 &(ltm.tm_year), &(ltm.tm_mon), &(ltm.tm_mday),
705 &(ltm.tm_hour), &(ltm.tm_min), &(ltm.tm_sec),
706 &zz) != 7) || (zz !=
'Z')) {
708 if ((sscanf((
const char *)(tsn1->data),
709 "%04d%02d%02d%02d%02d%02d%c",
710 &(ltm.tm_year), &(ltm.tm_mon), &(ltm.tm_mday),
711 &(ltm.tm_hour), &(ltm.tm_min), &(ltm.tm_sec),
712 &zz) != 7) || (zz !=
'Z')) {
722 if (ltm.tm_year < 50) {
724 }
else if (ltm.tm_year < 100) {
733 etime = mktime(<m);
748 #ifndef USEX509NAMEONELINE
749 BIO *mbio = BIO_new(BIO_s_mem());
750 X509_NAME_print_ex(mbio, nm, 0, XN_FLAG_SEP_MULTILINE);
752 long len = BIO_get_mem_data(mbio, &data);
758 char *xn = X509_NAME_oneline(nm, 0, 0);
void XrdCryptosslNameOneLine(X509_NAME *nm, XrdOucString &s)
int XrdCryptosslX509ParseBucket(XrdSutBucket *b, XrdCryptoX509Chain *chain)
int XrdCryptosslKDFunLen()
int XrdCryptosslX509ToFile(XrdCryptoX509 *x509, FILE *file, const char *fname)
int XrdCryptosslX509VerifyCB(int ok, X509_STORE_CTX *ctx)
int XrdCryptosslX509ChainToFile(XrdCryptoX509Chain *ch, const char *fn)
int XrdCryptosslX509ParseStack(XrdTlsPeerCerts *pc, XrdCryptoX509Chain *chain)
int XrdCryptosslKDFun(const char *pass, int plen, const char *salt, int slen, char *key, int klen)
XrdSutBucket * XrdCryptosslX509ExportChain(XrdCryptoX509Chain *chain, bool withprivatekey)
int XrdCryptosslX509ParseFile(const char *fname, XrdCryptoX509Chain *chain, const char *fkey)
time_t XrdCryptosslASN1toUTC(const ASN1_TIME *tsn1)
bool XrdCryptosslX509VerifyChain(XrdCryptoX509Chain *chain, int &errcode)
static int gErrVerifyChain
bool XrdCryptosslX509VerifyCert(XrdCryptoX509 *cert, XrdCryptoX509 *ref)
virtual XrdCryptoRSAdata Opaque()
XrdCryptoX509 * End() const
void PushBack(XrdCryptoX509 *c)
XrdCryptoX509 * SearchBySubject(const char *subject, ESearchMode mode=kExact)
virtual const char * Subject()
virtual void SetPKI(XrdCryptoX509data pki)
virtual XrdCryptoX509data Opaque()
virtual XrdCryptoRSA * PKI()
virtual const char * SubjectHash(int)
virtual const char * IssuerHash(int)
virtual const char * Issuer()
void insert(const int i, int start=-1)
int replace(const char *s1, const char *s2, int from=0, int to=-1)
int SetBuf(const char *nb=0, int ns=0)
X509 * getCert(bool upref=true)