diff --git a/cmake/FindOpenSSL.cmake b/cmake/FindOpenSSL.cmake index 6b2a878349b..e7cfc763b24 100644 --- a/cmake/FindOpenSSL.cmake +++ b/cmake/FindOpenSSL.cmake @@ -46,6 +46,9 @@ endif() set ( CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES} ) +check_function_exists(TLS_method HAVE_TLS) +compiler_define_if_found(HAVE_TLS HAVE_TLS) + check_function_exists(TLSv1_2_method HAVE_TLS12) compiler_define_if_found(HAVE_TLS12 HAVE_TLS12) diff --git a/src/XrdCrypto/XrdCryptoFactory.cc b/src/XrdCrypto/XrdCryptoFactory.cc index e1935558bd9..9a44e4ea5cf 100644 --- a/src/XrdCrypto/XrdCryptoFactory.cc +++ b/src/XrdCrypto/XrdCryptoFactory.cc @@ -358,7 +358,7 @@ XrdCryptoX509SignProxyReq_t XrdCryptoFactory::X509SignProxyReq() //______________________________________________________________________________ XrdCryptoX509CheckProxy3_t XrdCryptoFactory::X509CheckProxy3() { - // Sign a proxy request + // Check consistency of a GSI 3 compliant proxy ABSTRACTMETHOD("XrdCryptoFactory::X509CheckProxy3"); return 0; diff --git a/src/XrdCrypto/XrdCryptoFactory.hh b/src/XrdCrypto/XrdCryptoFactory.hh index cf2f8ec250d..322ccd20ebd 100644 --- a/src/XrdCrypto/XrdCryptoFactory.hh +++ b/src/XrdCrypto/XrdCryptoFactory.hh @@ -84,7 +84,8 @@ typedef int (*XrdCryptoX509ParseBucket_t)(XrdSutBucket *, XrdCryptoX509Chain *); // Proxies // The OID of the extension -#define gsiProxyCertInfo_OID "1.3.6.1.4.1.3536.1.222" +#define gsiProxyCertInfo_OLD_OID "1.3.6.1.4.1.3536.1.222" +#define gsiProxyCertInfo_OID "1.3.6.1.5.5.7.1.14" // check presence of proxyCertInfo extension (RFC 3820) typedef bool (*XrdCryptoProxyCertInfo_t)(const void *, int &, bool *); // set path length constraint @@ -105,7 +106,7 @@ typedef int (*XrdCryptoX509CreateProxyReq_t)(XrdCryptoX509 *, // sign a proxy certificate request typedef int (*XrdCryptoX509SignProxyReq_t)(XrdCryptoX509 *, XrdCryptoRSA *, XrdCryptoX509Req *, XrdCryptoX509 **); -// sign a proxy certificate request +// check consistency of a GSI 3 compliant proxy typedef int (*XrdCryptoX509CheckProxy3_t)(XrdCryptoX509 *, XrdOucString &); // get VOMS attributes diff --git a/src/XrdCrypto/XrdCryptogsiX509Chain.cc b/src/XrdCrypto/XrdCryptogsiX509Chain.cc index db8f8a71e59..8363ab778a3 100644 --- a/src/XrdCrypto/XrdCryptogsiX509Chain.cc +++ b/src/XrdCrypto/XrdCryptogsiX509Chain.cc @@ -176,6 +176,7 @@ bool XrdCryptogsiX509Chain::Verify(EX509ChainErr &errcode, x509ChainVerifyOpt_t int pxplen = -1; bool b; if (opt & kOptsRfc3820) { const void *extdata = xcer->GetExtension(gsiProxyCertInfo_OID); + if (!extdata) extdata = xcer->GetExtension(gsiProxyCertInfo_OLD_OID); if (!extdata || !cfact || !(cfact && (*(cfact->ProxyCertInfo()))(extdata, pxplen, &b))) { errcode = kMissingExtension; lastError = "rfc3820: "; @@ -244,7 +245,7 @@ bool XrdCryptogsiX509Chain::SubjectOK(EX509ChainErr &errcode, XrdCryptoX509 *xce if (pcn) { char *pcnn = 0; while ((pcnn = (char *) strstr(pcn+1,"/CN="))) - pcn = pcnn; + pcn = pcnn; ilen = (int)(pcn - xcer->Issuer()); } if (strncmp(xcer->Subject() + ilen,"/CN=",4)) { diff --git a/src/XrdCrypto/XrdCryptosslAux.cc b/src/XrdCrypto/XrdCryptosslAux.cc index f7b809ca179..23e648b239a 100644 --- a/src/XrdCrypto/XrdCryptosslAux.cc +++ b/src/XrdCrypto/XrdCryptosslAux.cc @@ -48,6 +48,16 @@ static int gErrVerifyChain = 0; XrdOucTrace *sslTrace = 0; +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_RSA) { + return NULL; + } + return pkey->pkey.rsa; +} +#endif + //____________________________________________________________________________ int XrdCryptosslX509VerifyCB(int ok, X509_STORE_CTX *ctx) { @@ -444,15 +454,12 @@ int XrdCryptosslX509ParseFile(const char *fname, // Get the public key EVP_PKEY *evpp = X509_get_pubkey((X509 *)(cert->Opaque())); if (evpp) { -#if OPENSSL_VERSION_NUMBER >= 0x10000000L - // evpp gets reset by the other call on >=1.0.0; to be investigated - if (PEM_read_bio_RSAPrivateKey(bkey,&(evpp->pkey.rsa),0,0)) { -#else - if (PEM_read_bio_PrivateKey(bkey,&evpp,0,0)) { -#endif + RSA *rsa = 0; + if (PEM_read_bio_RSAPrivateKey(bkey,&rsa,0,0)) { + EVP_PKEY_assign_RSA(evpp, rsa); DEBUG("RSA key completed for '"<Subject()<<"'"); // Test consistency - int rc = RSA_check_key(evpp->pkey.rsa); + int rc = RSA_check_key(EVP_PKEY_get0_RSA(evpp)); if (rc != 0) { // Update PKI in certificate cert->SetPKI((XrdCryptoX509data)evpp); @@ -567,10 +574,12 @@ int XrdCryptosslX509ParseBucket(XrdSutBucket *b, XrdCryptoX509Chain *chain) // Get the public key EVP_PKEY *evpp = X509_get_pubkey((X509 *)(cert->Opaque())); if (evpp) { - if (PEM_read_bio_PrivateKey(bkey,&evpp,0,0)) { + RSA *rsa = 0; + if (PEM_read_bio_RSAPrivateKey(bkey,&rsa,0,0)) { + EVP_PKEY_assign_RSA(evpp, rsa); DEBUG("RSA key completed "); // Test consistency - int rc = RSA_check_key(evpp->pkey.rsa); + int rc = RSA_check_key(EVP_PKEY_get0_RSA(evpp)); if (rc != 0) { // Update PKI in certificate cert->SetPKI((XrdCryptoX509data)evpp); @@ -598,7 +607,7 @@ int XrdCryptosslX509ParseBucket(XrdSutBucket *b, XrdCryptoX509Chain *chain) } //____________________________________________________________________________ -int XrdCryptosslASN1toUTC(ASN1_TIME *tsn1) +int XrdCryptosslASN1toUTC(const ASN1_TIME *tsn1) { // Function to convert from ASN1 time format into UTC // since Epoch (Jan 1, 1970) diff --git a/src/XrdCrypto/XrdCryptosslAux.hh b/src/XrdCrypto/XrdCryptosslAux.hh index b8b45581ba4..3cfc5310931 100644 --- a/src/XrdCrypto/XrdCryptosslAux.hh +++ b/src/XrdCrypto/XrdCryptosslAux.hh @@ -62,7 +62,7 @@ int XrdCryptosslX509ParseFile(const char *fname, XrdCryptoX509Chain *c); int XrdCryptosslX509ParseBucket(XrdSutBucket *b, XrdCryptoX509Chain *c); // // Function to convert from ASN1 time format into UTC since Epoch (Jan 1, 1970) -int XrdCryptosslASN1toUTC(ASN1_TIME *tsn1); +int XrdCryptosslASN1toUTC(const ASN1_TIME *tsn1); // Function to convert X509_NAME into a one-line human readable string void XrdCryptosslNameOneLine(X509_NAME *nm, XrdOucString &s); diff --git a/src/XrdCrypto/XrdCryptosslCipher.cc b/src/XrdCrypto/XrdCryptosslCipher.cc index e15462be4ea..4204df1ae3a 100644 --- a/src/XrdCrypto/XrdCryptosslCipher.cc +++ b/src/XrdCrypto/XrdCryptosslCipher.cc @@ -47,6 +47,91 @@ // // ---------------------------------------------------------------------------// +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static void DH_get0_pqg(const DH *dh, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + *p = dh->p; + if (q != NULL) + *q = dh->q; + if (g != NULL) + *g = dh->g; +} + +static int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + /* If the fields p and g in d are NULL, the corresponding input + * parameters MUST be non-NULL. q may remain NULL. + */ + if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL)) + return 0; + if (p != NULL) { + BN_free(dh->p); + dh->p = p; + } + if (q != NULL) { + BN_free(dh->q); + dh->q = q; + } + if (g != NULL) { + BN_free(dh->g); + dh->g = g; + } + if (q != NULL) { + dh->length = BN_num_bits(q); + } + return 1; +} + +static void DH_get0_key(const DH *dh, + const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = dh->pub_key; + if (priv_key != NULL) + *priv_key = dh->priv_key; +} + +static int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) +{ + /* If the field pub_key in dh is NULL, the corresponding input + * parameters MUST be non-NULL. The priv_key field may + * be left NULL. + */ + if (dh->pub_key == NULL && pub_key == NULL) + return 0; + if (pub_key != NULL) { + BN_free(dh->pub_key); + dh->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(dh->priv_key); + dh->priv_key = priv_key; + } + return 1; +} + +static int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) +{ + /* If the field pub_key in d is NULL, the corresponding input + * parameters MUST be non-NULL. The priv_key field may + * be left NULL. + */ + if (d->pub_key == NULL && pub_key == NULL) + return 0; + if (pub_key != NULL) { + BN_free(d->pub_key); + d->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(d->priv_key); + d->priv_key = priv_key; + } + return 1; +} +#endif + //_____________________________________________________________________________ bool XrdCryptosslCipher::IsSupported(const char *cip) { @@ -64,6 +149,7 @@ XrdCryptosslCipher::XrdCryptosslCipher(const char *t, int l) // Used to create ciphers valid = 0; + ctx = 0; fIV = 0; lIV = 0; cipher = 0; @@ -73,7 +159,7 @@ XrdCryptosslCipher::XrdCryptosslCipher(const char *t, int l) // Check and set type char cipnam[64] = {"bf-cbc"}; if (t && strcmp(t,"default")) { - strcpy(cipnam,t); + strcpy(cipnam,t); cipnam[63] = 0; } cipher = EVP_get_cipherbyname(cipnam); @@ -87,25 +173,27 @@ XrdCryptosslCipher::XrdCryptosslCipher(const char *t, int l) char *ktmp = XrdSutRndm::GetBuffer(lgen); if (ktmp) { // Init context - EVP_CIPHER_CTX_init(&ctx); - valid = 1; - // Try setting the key length - if (l && l != ldef) { - EVP_CipherInit_ex(&ctx, cipher, 0, 0, 0, 1); - EVP_CIPHER_CTX_set_key_length(&ctx,l); - EVP_CipherInit_ex(&ctx, 0, 0, (unsigned char *)ktmp, 0, 1); - if (l == EVP_CIPHER_CTX_key_length(&ctx)) { - // Use the l bytes at ktmp - SetBuffer(l,ktmp); - deflength = 0; + ctx = EVP_CIPHER_CTX_new(); + if (ctx) { + valid = 1; + // Try setting the key length + if (l && l != ldef) { + EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1); + EVP_CIPHER_CTX_set_key_length(ctx,l); + EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)ktmp, 0, 1); + if (l == EVP_CIPHER_CTX_key_length(ctx)) { + // Use the l bytes at ktmp + SetBuffer(l,ktmp); + deflength = 0; + } } + if (!Length()) { + EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)ktmp, 0, 1); + SetBuffer(ldef,ktmp); + } + // Set also the type + SetType(cipnam); } - if (!Length()) { - EVP_CipherInit_ex(&ctx, cipher, 0, (unsigned char *)ktmp, 0, 1); - SetBuffer(ldef,ktmp); - } - // Set also the type - SetType(cipnam); // Cleanup delete[] ktmp; } @@ -125,6 +213,7 @@ XrdCryptosslCipher::XrdCryptosslCipher(const char *t, int l, // the initialization vector at iv. // Used to import ciphers. valid = 0; + ctx = 0; fIV = 0; lIV = 0; fDH = 0; @@ -134,22 +223,24 @@ XrdCryptosslCipher::XrdCryptosslCipher(const char *t, int l, // Check and set type char cipnam[64] = {"bf-cbc"}; if (t && strcmp(t,"default")) { - strcpy(cipnam,t); + strcpy(cipnam,t); cipnam[63] = 0; } cipher = EVP_get_cipherbyname(cipnam); if (cipher) { // Init context - EVP_CIPHER_CTX_init(&ctx); - // Set the key - SetBuffer(l,k); - if (l != EVP_CIPHER_key_length(cipher)) - deflength = 0; - // Set also the type - SetType(cipnam); - // Set validity flag - valid = 1; + ctx = EVP_CIPHER_CTX_new(); + if (ctx) { + // Set the key + SetBuffer(l,k); + if (l != EVP_CIPHER_key_length(cipher)) + deflength = 0; + // Set also the type + SetType(cipnam); + // Set validity flag + valid = 1; + } } // // Init cipher @@ -159,11 +250,11 @@ XrdCryptosslCipher::XrdCryptosslCipher(const char *t, int l, SetIV(liv,iv); if (deflength) { - EVP_CipherInit_ex(&ctx, cipher, 0, (unsigned char *)Buffer(), 0, 1); + EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)Buffer(), 0, 1); } else { - EVP_CipherInit_ex(&ctx, cipher, 0, 0, 0, 1); - EVP_CIPHER_CTX_set_key_length(&ctx,Length()); - EVP_CipherInit_ex(&ctx, 0, 0, (unsigned char *)Buffer(), 0, 1); + EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1); + EVP_CIPHER_CTX_set_key_length(ctx,Length()); + EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)Buffer(), 0, 1); } } } @@ -175,6 +266,7 @@ XrdCryptosslCipher::XrdCryptosslCipher(XrdSutBucket *bck) // Initialize a cipher of type t and length l using the key at k // Used to import ciphers. valid = 0; + ctx = 0; fIV = 0; lIV = 0; fDH = 0; @@ -222,7 +314,7 @@ XrdCryptosslCipher::XrdCryptosslCipher(XrdSutBucket *bck) SetType(buf); } else { valid = 0; - } + } delete[] buf; } else valid = 0; @@ -258,13 +350,15 @@ XrdCryptosslCipher::XrdCryptosslCipher(XrdSutBucket *bck) if (lp > 0 || lg > 0 || lpub > 0 || lpri > 0) { if ((fDH = DH_new())) { char *buf = 0; + BIGNUM *p = NULL, *g = NULL; + BIGNUM *pub = NULL, *pri = NULL; // p if (lp > 0) { buf = new char[lp+1]; if (buf) { memcpy(buf,bp+cur,lp); buf[lp] = 0; - BN_hex2bn(&(fDH->p),buf); + BN_hex2bn(&p,buf); delete[] buf; } else valid = 0; @@ -276,19 +370,20 @@ XrdCryptosslCipher::XrdCryptosslCipher(XrdSutBucket *bck) if (buf) { memcpy(buf,bp+cur,lg); buf[lg] = 0; - BN_hex2bn(&(fDH->g),buf); + BN_hex2bn(&g,buf); delete[] buf; } else valid = 0; cur += lg; } + DH_set0_pqg(fDH, p, NULL, g); // pub_key if (lpub > 0) { buf = new char[lpub+1]; if (buf) { memcpy(buf,bp+cur,lpub); buf[lpub] = 0; - BN_hex2bn(&(fDH->pub_key),buf); + BN_hex2bn(&pub,buf); delete[] buf; } else valid = 0; @@ -300,12 +395,13 @@ XrdCryptosslCipher::XrdCryptosslCipher(XrdSutBucket *bck) if (buf) { memcpy(buf,bp+cur,lpri); buf[lpri] = 0; - BN_hex2bn(&(fDH->priv_key),buf); + BN_hex2bn(&pri,buf); delete[] buf; } else valid = 0; cur += lpri; } + DH_set0_key(fDH, pub, pri); int dhrc = 0; DH_check(fDH,&dhrc); if (dhrc == 0) @@ -318,15 +414,19 @@ XrdCryptosslCipher::XrdCryptosslCipher(XrdSutBucket *bck) // Init cipher if (valid) { // Init context - EVP_CIPHER_CTX_init(&ctx); - if (deflength) { - EVP_CipherInit_ex(&ctx, cipher, 0, (unsigned char *)Buffer(), 0, 1); - } else { - EVP_CipherInit_ex(&ctx, cipher, 0, 0, 0, 1); - EVP_CIPHER_CTX_set_key_length(&ctx,Length()); - EVP_CipherInit_ex(&ctx, 0, 0, (unsigned char *)Buffer(), 0, 1); - } - } else { + ctx = EVP_CIPHER_CTX_new(); + if (ctx) { + if (deflength) { + EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)Buffer(), 0, 1); + } else { + EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1); + EVP_CIPHER_CTX_set_key_length(ctx,Length()); + EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)Buffer(), 0, 1); + } + } else + valid = 0; + } + if (!valid) { Cleanup(); } } @@ -346,6 +446,7 @@ XrdCryptosslCipher::XrdCryptosslCipher(int bits, char *pub, EPNAME("sslCipher::XrdCryptosslCipher"); valid = 0; + ctx = 0; fIV = 0; lIV = 0; fDH = 0; @@ -356,19 +457,21 @@ XrdCryptosslCipher::XrdCryptosslCipher(int bits, char *pub, DEBUG("generate DH full key"); // // at least 128 bits - bits = (bits < kDHMINBITS) ? kDHMINBITS : bits; + bits = (bits < kDHMINBITS) ? kDHMINBITS : bits; // // Generate params for DH object - if ((fDH = DH_generate_parameters(bits,DH_GENERATOR_5,0,0))) { + fDH = DH_new(); + if (fDH && DH_generate_parameters_ex(fDH, bits, DH_GENERATOR_5, NULL)) { int prc = 0; DH_check(fDH,&prc); if (prc == 0) { // // Generate DH key if (DH_generate_key(fDH)) { - valid = 1; // Init context - EVP_CIPHER_CTX_init(&ctx); + ctx = EVP_CIPHER_CTX_new(); + if (ctx) + valid = 1; } } } @@ -427,37 +530,39 @@ XrdCryptosslCipher::XrdCryptosslCipher(int bits, char *pub, // If a valid key has been computed, set the cipher if (valid) { // Init context - EVP_CIPHER_CTX_init(&ctx); - - // Check and set type - char cipnam[64] = {"bf-cbc"}; - if (t && strcmp(t,"default")) { - strcpy(cipnam,t); - cipnam[63] = 0; - } - if ((cipher = EVP_get_cipherbyname(cipnam))) { - // At most EVP_MAX_KEY_LENGTH bytes - ltmp = (ltmp > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : ltmp; - int ldef = EVP_CIPHER_key_length(cipher); - // Try setting the key length - if (ltmp != ldef) { - EVP_CipherInit_ex(&ctx, cipher, 0, 0, 0, 1); - EVP_CIPHER_CTX_set_key_length(&ctx,ltmp); - EVP_CipherInit_ex(&ctx, 0, 0, (unsigned char *)ktmp, 0, 1); - if (ltmp == EVP_CIPHER_CTX_key_length(&ctx)) { - // Use the ltmp bytes at ktmp - SetBuffer(ltmp,ktmp); - deflength = 0; - } + ctx = EVP_CIPHER_CTX_new(); + if (ctx) { + // Check and set type + char cipnam[64] = {"bf-cbc"}; + if (t && strcmp(t,"default")) { + strcpy(cipnam,t); + cipnam[63] = 0; } - if (!Length()) { - EVP_CipherInit_ex(&ctx, cipher, 0, (unsigned char *)ktmp, 0, 1); - SetBuffer(ldef,ktmp); + if ((cipher = EVP_get_cipherbyname(cipnam))) { + // At most EVP_MAX_KEY_LENGTH bytes + ltmp = (ltmp > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : ltmp; + int ldef = EVP_CIPHER_key_length(cipher); + // Try setting the key length + if (ltmp != ldef) { + EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1); + EVP_CIPHER_CTX_set_key_length(ctx,ltmp); + EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)ktmp, 0, 1); + if (ltmp == EVP_CIPHER_CTX_key_length(ctx)) { + // Use the ltmp bytes at ktmp + SetBuffer(ltmp,ktmp); + deflength = 0; + } + } + if (!Length()) { + EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)ktmp, 0, 1); + SetBuffer(ldef,ktmp); + } + // Set also the type + SetType(cipnam); } - // Set also the type - SetType(cipnam); - } - } + } else + valid = 0; + } // Cleanup if (ktmp) {delete[] ktmp; ktmp = 0;} } @@ -476,10 +581,12 @@ XrdCryptosslCipher::XrdCryptosslCipher(const XrdCryptosslCipher &c) // Basics deflength = c.deflength; valid = c.valid; + ctx = 0; // IV lIV = 0; fIV = 0; SetIV(c.lIV,c.fIV); + // Cipher cipher = c.cipher; // Set the key @@ -491,10 +598,12 @@ XrdCryptosslCipher::XrdCryptosslCipher(const XrdCryptosslCipher &c) if (valid && c.fDH) { valid = 0; if ((fDH = DH_new())) { - if (c.fDH->p) fDH->p = BN_dup(c.fDH->p); - if (c.fDH->g) fDH->g = BN_dup(c.fDH->g); - if (c.fDH->pub_key) fDH->pub_key = BN_dup(c.fDH->pub_key); - if (c.fDH->priv_key) fDH->priv_key = BN_dup(c.fDH->priv_key); + const BIGNUM *p, *g; + DH_get0_pqg(c.fDH, &p, NULL, &g); + DH_set0_pqg(fDH, p ? BN_dup(p) : NULL, NULL, g ? BN_dup(g) : NULL); + const BIGNUM *pub, *pri; + DH_get0_key(c.fDH, &pub, &pri); + DH_set0_key(fDH, pub ? BN_dup(pub) : NULL, pri ? BN_dup(pri) : NULL); int dhrc = 0; DH_check(fDH,&dhrc); if (dhrc == 0) @@ -503,8 +612,11 @@ XrdCryptosslCipher::XrdCryptosslCipher(const XrdCryptosslCipher &c) } if (valid) { // Init context - EVP_CIPHER_CTX_init(&ctx); - } else { + ctx = EVP_CIPHER_CTX_new(); + if (!ctx) + valid = 0; + } + if (!valid) { Cleanup(); } } @@ -520,7 +632,7 @@ XrdCryptosslCipher::~XrdCryptosslCipher() // Cleanups if (valid) - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); Cleanup(); } @@ -586,7 +698,7 @@ bool XrdCryptosslCipher::Finalize(char *pub, int /*lpub*/, const char *t) // Check and set type char cipnam[64] = {"bf-cbc"}; if (t && strcmp(t,"default")) { - strcpy(cipnam,t); + strcpy(cipnam,t); cipnam[63] = 0; } if ((cipher = EVP_get_cipherbyname(cipnam))) { @@ -595,30 +707,30 @@ bool XrdCryptosslCipher::Finalize(char *pub, int /*lpub*/, const char *t) int ldef = EVP_CIPHER_key_length(cipher); // Try setting the key length if (ltmp != ldef) { - EVP_CipherInit_ex(&ctx, cipher, 0, 0, 0, 1); - EVP_CIPHER_CTX_set_key_length(&ctx,ltmp); - EVP_CipherInit_ex(&ctx, 0, 0, (unsigned char *)ktmp, 0, 1); - if (ltmp == EVP_CIPHER_CTX_key_length(&ctx)) { + EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1); + EVP_CIPHER_CTX_set_key_length(ctx,ltmp); + EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)ktmp, 0, 1); + if (ltmp == EVP_CIPHER_CTX_key_length(ctx)) { // Use the ltmp bytes at ktmp SetBuffer(ltmp,ktmp); deflength = 0; } } if (!Length()) { - EVP_CipherInit_ex(&ctx, cipher, 0, (unsigned char *)ktmp, 0, 1); + EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)ktmp, 0, 1); SetBuffer(ldef,ktmp); } // Set also the type SetType(cipnam); } - } + } // Cleanup if (ktmp) {delete[] ktmp; ktmp = 0;} } // Cleanup, if invalid if (!valid) { - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); Cleanup(); } @@ -629,7 +741,7 @@ bool XrdCryptosslCipher::Finalize(char *pub, int /*lpub*/, const char *t) //_____________________________________________________________________________ int XrdCryptosslCipher::Publen() { - // Minimu length of export format of public key + // Minimum length of export format of public key static int lhdr = strlen("-----BEGIN DH PARAMETERS-----" "-----END DH PARAMETERS-----") + 3; if (fDH) { @@ -655,7 +767,9 @@ char *XrdCryptosslCipher::Public(int &lpub) if (fDH) { // // Calculate and write public key hex - char *phex = BN_bn2hex(fDH->pub_key); + const BIGNUM *pub; + DH_get0_key(fDH, &pub, NULL); + char *phex = BN_bn2hex(pub); int lhex = strlen(phex); // // Prepare bio to export info buffer @@ -714,7 +828,7 @@ void XrdCryptosslCipher::PrintPublic(BIGNUM *pub) // Use a DSA structure to export the public part DSA *dsa = DSA_new(); if (dsa) { - dsa->pub_key = BN_dup(pub); + DSA_set0_key(dsa, BN_dup(pub), NULL); // Write public key to BIO PEM_write_bio_DSA_PUBKEY(biop,dsa); // Read key from BIO to buf @@ -746,10 +860,14 @@ XrdSutBucket *XrdCryptosslCipher::AsBucket() kXR_int32 lbuf = Length(); kXR_int32 ltyp = Type() ? strlen(Type()) : 0; kXR_int32 livc = lIV; - char *cp = (fDH && fDH->p) ? BN_bn2hex(fDH->p) : 0; - char *cg = (fDH && fDH->g) ? BN_bn2hex(fDH->g) : 0; - char *cpub = (fDH && fDH->pub_key) ? BN_bn2hex(fDH->pub_key) : 0; - char *cpri = (fDH && fDH->priv_key) ? BN_bn2hex(fDH->priv_key) : 0; + const BIGNUM *p, *g; + const BIGNUM *pub, *pri; + DH_get0_pqg(fDH, &p, NULL, &g); + DH_get0_key(fDH, &pub, &pri); + char *cp = BN_bn2hex(p); + char *cg = BN_bn2hex(g); + char *cpub = BN_bn2hex(pub); + char *cpri = BN_bn2hex(pri); kXR_int32 lp = cp ? strlen(cp) : 0; kXR_int32 lg = cg ? strlen(cg) : 0; kXR_int32 lpub = cpub ? strlen(cpub) : 0; @@ -893,16 +1011,16 @@ int XrdCryptosslCipher::EncDec(int enc, const char *in, int lin, char *out) // The outbut buffer must be provided by the caller for at least // EncOutLength(lin) or DecOutLength(lin) bytes. // Returns number of meaningful bytes in out, or 0 in case of problems - EPNAME("Cipher::EncDec"); + EPNAME("Cipher::EncDec"); int lout = 0; // Check inputs if (!in || lin <= 0 || !out) { - DEBUG("wrong inputs arguments"); - if (!in) DEBUG("in: "< #include +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_RSA) { + return NULL; + } + return pkey->pkey.rsa; +} + +static void RSA_get0_key(const RSA *r, + const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +{ + if (n != NULL) + *n = r->n; + if (e != NULL) + *e = r->e; + if (d != NULL) + *d = r->d; +} +#endif + //_____________________________________________________________________________ XrdCryptosslRSA::XrdCryptosslRSA(int bits, int exp) { @@ -65,27 +86,44 @@ XrdCryptosslRSA::XrdCryptosslRSA(int bits, int exp) bits = (bits >= XrdCryptoMinRSABits) ? bits : XrdCryptoMinRSABits; // If pubex is not odd, use default - if (!(exp & 1<<1)) + if (!(exp & 1)) exp = XrdCryptoDefRSAExp; // 65537 (0x10001) - DEBUG("bits: "<pkey.rsa) != 0) { + if (RSA_check_key(EVP_PKEY_get0_RSA(key)) != 0) { fEVP = key; // Update status status = kComplete; @@ -155,7 +193,9 @@ XrdCryptosslRSA::XrdCryptosslRSA(const XrdCryptosslRSA &r) : XrdCryptoRSA() } // If the given key is set, copy it via a bio - bool publiconly = (r.fEVP->pkey.rsa->d == 0); + const BIGNUM *d; + RSA_get0_key(EVP_PKEY_get0_RSA(r.fEVP), NULL, NULL, &d); + bool publiconly = (d == 0); // // Bio for exporting the pub key BIO *bcpy = BIO_new(BIO_s_mem()); @@ -177,7 +217,7 @@ XrdCryptosslRSA::XrdCryptosslRSA(const XrdCryptosslRSA &r) : XrdCryptoRSA() } else { if ((fEVP = PEM_read_bio_PrivateKey(bcpy,0,0,0))) { // Check consistency - if (RSA_check_key(fEVP->pkey.rsa) != 0) { + if (RSA_check_key(EVP_PKEY_get0_RSA(fEVP)) != 0) { // Update status status = kComplete; } @@ -205,9 +245,9 @@ int XrdCryptosslRSA::GetOutlen(int lin) { // Get minimal length of output buffer - int lcmax = RSA_size(fEVP->pkey.rsa) - 42; + int lcmax = RSA_size(EVP_PKEY_get0_RSA(fEVP)) - 42; - return ((lin / lcmax) + 1) * RSA_size(fEVP->pkey.rsa); + return ((lin / lcmax) + 1) * RSA_size(EVP_PKEY_get0_RSA(fEVP)); } //_____________________________________________________________________________ @@ -306,7 +346,7 @@ void XrdCryptosslRSA::Dump() //_____________________________________________________________________________ int XrdCryptosslRSA::GetPublen() { - // Minimu length of export format of public key + // Minimum length of export format of public key if (publen < 0) { // Bio for exporting the pub key @@ -370,7 +410,7 @@ int XrdCryptosslRSA::ExportPublic(char *out, int) //_____________________________________________________________________________ int XrdCryptosslRSA::GetPrilen() { - // Minimu length of export format of private key + // Minimum length of export format of private key if (prilen < 0) { // Bio for exporting the private key @@ -455,7 +495,7 @@ int XrdCryptosslRSA::EncryptPrivate(const char *in, int lin, char *out, int lout // // Private encoding ... - int lcmax = RSA_size(fEVP->pkey.rsa) - 11; // Magic number (= 2*sha1_outlen + 2) + int lcmax = RSA_size(EVP_PKEY_get0_RSA(fEVP)) - 11; // Magic number (= 2*sha1_outlen + 2) int lout = 0; int len = lin; int kk = 0; @@ -465,7 +505,7 @@ int XrdCryptosslRSA::EncryptPrivate(const char *in, int lin, char *out, int lout int lc = (len > lcmax) ? lcmax : len ; if ((lout = RSA_private_encrypt(lc, (unsigned char *)&in[kk], (unsigned char *)&out[ke], - fEVP->pkey.rsa, RSA_PKCS1_PADDING)) < 0) { + EVP_PKEY_get0_RSA(fEVP), RSA_PKCS1_PADDING)) < 0) { char serr[120]; ERR_error_string(ERR_get_error(), serr); DEBUG("error: " <pkey.rsa) - 42; // Magic number (= 2*sha1_outlen + 2) + int lcmax = RSA_size(EVP_PKEY_get0_RSA(fEVP)) - 42; // Magic number (= 2*sha1_outlen + 2) int lout = 0; int len = lin; int kk = 0; @@ -516,7 +556,7 @@ int XrdCryptosslRSA::EncryptPublic(const char *in, int lin, char *out, int loutm int lc = (len > lcmax) ? lcmax : len ; if ((lout = RSA_public_encrypt(lc, (unsigned char *)&in[kk], (unsigned char *)&out[ke], - fEVP->pkey.rsa, RSA_PKCS1_OAEP_PADDING)) < 0) { + EVP_PKEY_get0_RSA(fEVP), RSA_PKCS1_OAEP_PADDING)) < 0) { char serr[120]; ERR_error_string(ERR_get_error(), serr); DEBUG("error: " <pkey.rsa); + int lcmax = RSA_size(EVP_PKEY_get0_RSA(fEVP)); int kk = 0; int ke = 0; @@ -566,7 +606,7 @@ int XrdCryptosslRSA::DecryptPrivate(const char *in, int lin, char *out, int lout while (len > 0 && ke <= (loutmax - lout)) { if ((lout = RSA_private_decrypt(lcmax, (unsigned char *)&in[kk], (unsigned char *)&out[ke], - fEVP->pkey.rsa, RSA_PKCS1_OAEP_PADDING)) < 0) { + EVP_PKEY_get0_RSA(fEVP), RSA_PKCS1_OAEP_PADDING)) < 0) { char serr[120]; ERR_error_string(ERR_get_error(), serr); DEBUG("error: " <pkey.rsa); + int lcmax = RSA_size(EVP_PKEY_get0_RSA(fEVP)); int kk = 0; int ke = 0; @@ -615,7 +655,7 @@ int XrdCryptosslRSA::DecryptPublic(const char *in, int lin, char *out, int loutm while (len > 0 && ke <= (loutmax - lout)) { if ((lout = RSA_public_decrypt(lcmax, (unsigned char *)&in[kk], (unsigned char *)&out[ke], - fEVP->pkey.rsa, RSA_PKCS1_PADDING)) < 0) { + EVP_PKEY_get0_RSA(fEVP), RSA_PKCS1_PADDING)) < 0) { char serr[120]; ERR_error_string(ERR_get_error(), serr); PRINT("error: " < +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_RSA) { + return NULL; + } + return pkey->pkey.rsa; +} +#endif + #define BIO_PRINT(b,c) \ BUF_MEM *bptr; \ BIO_get_mem_ptr(b, &bptr); \ @@ -149,7 +159,7 @@ XrdCryptosslX509::XrdCryptosslX509(const char *cf, const char *kf) if ((evpp = PEM_read_PrivateKey(fk,0,0,0))) { DEBUG("RSA key completed "); // Test consistency - if (RSA_check_key(evpp->pkey.rsa) != 0) { + if (RSA_check_key(EVP_PKEY_get0_RSA(evpp)) != 0) { // Save it in pki pki = new XrdCryptosslRSA(evpp); } @@ -509,7 +519,7 @@ const char *XrdCryptosslX509::IssuerHash(int alg) if (cert) { char chash[30] = {0}; snprintf(chash, sizeof(chash), - "%08lx.0",X509_NAME_hash_old(cert->cert_info->issuer)); + "%08lx.0",X509_NAME_hash_old(X509_get_issuer_name(cert))); issueroldhash = chash; } else { DEBUG("WARNING: no certificate available - cannot extract issuer hash (md5)"); @@ -529,7 +539,7 @@ const char *XrdCryptosslX509::IssuerHash(int alg) if (cert) { char chash[30] = {0}; snprintf(chash, sizeof(chash), - "%08lx.0",X509_NAME_hash(cert->cert_info->issuer)); + "%08lx.0",X509_NAME_hash(X509_get_issuer_name(cert))); issuerhash = chash; } else { DEBUG("WARNING: no certificate available - cannot extract issuer hash (default)"); @@ -556,7 +566,7 @@ const char *XrdCryptosslX509::SubjectHash(int alg) if (cert) { char chash[30] = {0}; snprintf(chash, sizeof(chash), - "%08lx.0",X509_NAME_hash_old(cert->cert_info->subject)); + "%08lx.0",X509_NAME_hash_old(X509_get_subject_name(cert))); subjectoldhash = chash; } else { DEBUG("WARNING: no certificate available - cannot extract subject hash (md5)"); @@ -576,7 +586,7 @@ const char *XrdCryptosslX509::SubjectHash(int alg) if (cert) { char chash[30] = {0}; snprintf(chash, sizeof(chash), - "%08lx.0",X509_NAME_hash(cert->cert_info->subject)); + "%08lx.0",X509_NAME_hash(X509_get_subject_name(cert))); subjecthash = chash; } else { DEBUG("WARNING: no certificate available - cannot extract subject hash (default)"); @@ -808,8 +818,8 @@ int XrdCryptosslX509::DumpExtensions(bool dumpunknown) PRINT(i << ": found extension '"<value->data; - long length = xpiext->value->length; + XRDGSI_CONST unsigned char *pp = (XRDGSI_CONST unsigned char *) X509_EXTENSION_get_data(xpiext)->data; + long length = X509_EXTENSION_get_data(xpiext)->length; int ret = FillUnknownExt(&pp, length, dumpunknown); PRINT("ret: " << ret); } @@ -920,13 +930,11 @@ int XrdCryptosslX509::FillUnknownExt(XRDGSI_CONST unsigned char **pp, long lengt if (dump) PRINT("ERROR:AOBJ: BAD OBJECT"); } } else if (tag == V_ASN1_BOOLEAN) { - opp = op; - int ii = d2i_ASN1_BOOLEAN(NULL,&opp,len+hl); - if (ii < 0) { + if (len != 1) { if (dump) PRINT("ERROR:BOOL: Bad boolean"); goto end; } - if (dump) PRINT("BOOL:"<< ii); + if (dump) PRINT("BOOL:"<< p[0]); } else if (tag == V_ASN1_BMPSTRING) { /* do the BMP thang */ } else if (tag == V_ASN1_OCTET_STRING) { @@ -964,7 +972,7 @@ int XrdCryptosslX509::FillUnknownExt(XRDGSI_CONST unsigned char **pp, long lengt } } if (os) { - M_ASN1_OCTET_STRING_free(os); + ASN1_OCTET_STRING_free(os); os = 0; } } else if (tag == V_ASN1_INTEGER) { @@ -990,7 +998,7 @@ int XrdCryptosslX509::FillUnknownExt(XRDGSI_CONST unsigned char **pp, long lengt } else { if (dump) PRINT("ERROR:AINT: BAD INTEGER"); } - M_ASN1_INTEGER_free(bs); + ASN1_INTEGER_free(bs); } else if (tag == V_ASN1_ENUMERATED) { ASN1_ENUMERATED *bs; int i; @@ -1014,7 +1022,7 @@ int XrdCryptosslX509::FillUnknownExt(XRDGSI_CONST unsigned char **pp, long lengt } else { if (dump) PRINT("ERROR:AENU: BAD ENUMERATED"); } - M_ASN1_ENUMERATED_free(bs); + ASN1_ENUMERATED_free(bs); } if (!nl && dump) PRINT(" "); @@ -1030,7 +1038,7 @@ int XrdCryptosslX509::FillUnknownExt(XRDGSI_CONST unsigned char **pp, long lengt ret = 1; end: if (o) ASN1_OBJECT_free(o); - if (os) M_ASN1_OCTET_STRING_free(os); + if (os) ASN1_OCTET_STRING_free(os); *pp = p; if (dump) PRINT("ret: "< #include +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define X509_REVOKED_get0_revocationDate(x) (x)->revocationDate +#define X509_REVOKED_get0_serialNumber(x) (x)->serialNumber +#define X509_CRL_get0_lastUpdate X509_CRL_get_lastUpdate +#define X509_CRL_get0_nextUpdate X509_CRL_get_nextUpdate +#endif + //_____________________________________________________________________________ XrdCryptosslX509Crl::XrdCryptosslX509Crl(const char *cf, int opt) : XrdCryptoX509Crl() @@ -391,7 +398,7 @@ int XrdCryptosslX509Crl::LoadCache() #endif /* OPENSSL */ if (rev) { BIGNUM *bn = BN_new(); - ASN1_INTEGER_to_BN(rev->serialNumber, bn); + ASN1_INTEGER_to_BN(X509_REVOKED_get0_serialNumber(rev), bn); tagser = BN_bn2hex(bn); BN_free(bn); TRACE(Dump, "certificate with serial number: "<mtime = XrdCryptosslASN1toUTC(rev->revocationDate); + cent->mtime = XrdCryptosslASN1toUTC(X509_REVOKED_get0_revocationDate(rev)); // Release the string for the serial number OPENSSL_free(tagser); } @@ -426,7 +433,7 @@ int XrdCryptosslX509Crl::LastUpdate() // Make sure we have a CRL if (crl) // Extract UTC time in secs from Epoch - lastupdate = XrdCryptosslASN1toUTC(X509_CRL_get_lastUpdate(crl)); + lastupdate = XrdCryptosslASN1toUTC(X509_CRL_get0_lastUpdate(crl)); } // return what we have return lastupdate; @@ -442,7 +449,7 @@ int XrdCryptosslX509Crl::NextUpdate() // Make sure we have a CRL if (crl) // Extract UTC time in secs from Epoch - nextupdate = XrdCryptosslASN1toUTC(X509_CRL_get_nextUpdate(crl)); + nextupdate = XrdCryptosslASN1toUTC(X509_CRL_get0_nextUpdate(crl)); } // return what we have return nextupdate; @@ -487,7 +494,7 @@ const char *XrdCryptosslX509Crl::IssuerHash(int alg) if (crl) { char chash[30] = {0}; snprintf(chash, sizeof(chash), - "%08lx.0",X509_NAME_hash_old(crl->crl->issuer)); + "%08lx.0",X509_NAME_hash_old(X509_CRL_get_issuer(crl))); issueroldhash = chash; } else { DEBUG("WARNING: no certificate available - cannot extract issuer hash (md5)"); @@ -507,7 +514,7 @@ const char *XrdCryptosslX509Crl::IssuerHash(int alg) if (crl) { char chash[30] = {0}; snprintf(chash, sizeof(chash), - "%08lx.0",X509_NAME_hash(crl->crl->issuer)); + "%08lx.0",X509_NAME_hash(X509_CRL_get_issuer(crl))); issuerhash = chash; } else { DEBUG("WARNING: no certificate available - cannot extract issuer hash (default)"); diff --git a/src/XrdCrypto/XrdCryptosslX509Req.cc b/src/XrdCrypto/XrdCryptosslX509Req.cc index 53b59b41be5..28621ab2696 100644 --- a/src/XrdCrypto/XrdCryptosslX509Req.cc +++ b/src/XrdCrypto/XrdCryptosslX509Req.cc @@ -190,7 +190,7 @@ const char *XrdCryptosslX509Req::SubjectHash(int alg) if (creq) { char chash[30] = {0}; snprintf(chash, sizeof(chash), - "%08lx.0",X509_NAME_hash_old(creq->req_info->subject)); + "%08lx.0",X509_NAME_hash_old(X509_REQ_get_subject_name(creq))); subjectoldhash = chash; } else { DEBUG("WARNING: no certificate available - cannot extract subject hash (md5)"); @@ -210,7 +210,7 @@ const char *XrdCryptosslX509Req::SubjectHash(int alg) if (creq) { char chash[30] = {0}; snprintf(chash, sizeof(chash), - "%08lx.0",X509_NAME_hash(creq->req_info->subject)); + "%08lx.0",X509_NAME_hash(X509_REQ_get_subject_name(creq))); subjecthash = chash; } else { DEBUG("WARNING: no certificate available - cannot extract subject hash (default)"); diff --git a/src/XrdCrypto/XrdCryptosslgsiAux.cc b/src/XrdCrypto/XrdCryptosslgsiAux.cc index 22b600b29a7..393fc79e9fd 100644 --- a/src/XrdCrypto/XrdCryptosslgsiAux.cc +++ b/src/XrdCrypto/XrdCryptosslgsiAux.cc @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include #include @@ -105,6 +105,16 @@ # define XRDGSI_CONST #endif +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_RSA) { + return NULL; + } + return pkey->pkey.rsa; +} +#endif + int XrdCryptosslX509Asn1PrintInfo(int tag, int xclass, int constructed, int indent); int XrdCryptosslX509FillUnknownExt(XRDGSI_CONST unsigned char **pp, long length); int XrdCryptosslX509FillVOMS(XRDGSI_CONST unsigned char **pp, @@ -115,290 +125,14 @@ int XrdCryptosslX509FillVOMS(XRDGSI_CONST unsigned char **pp, // Handlers of the ProxyCertInfo extension following RFC3820 // // // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// - -// -// Types describing the ProxyCertInfo extension -typedef struct { - ASN1_OBJECT *policyLanguage; - ASN1_OCTET_STRING *policy; -} gsiProxyPolicy_t; -// -typedef struct { - ASN1_INTEGER *proxyCertPathLengthConstraint; - gsiProxyPolicy_t *proxyPolicy; -} gsiProxyCertInfo_t; -// -// Some function ID codes as in asn1.h: the ASN1 macros require something -// though not sure we really need them. -// (not yet used above 299: keep some margin) -#define ASN1_F_GSIPROXYCERTINFO_NEW 500 -#define ASN1_F_D2I_GSIPROXYCERTINFO 501 -#define ASN1_F_GSIPROXYPOLICY_NEW 510 -#define ASN1_F_D2I_GSIPROXYPOLICY 511 - -// ------------------------------------------------------------------------- -// -// Version of OBJ_txt2obj with a bug fix introduced starting -// with some 0.9.6 versions -static ASN1_OBJECT *OBJ_txt2obj_fix(const char *s, int no_name) -{ - int nid = NID_undef; - ASN1_OBJECT *op=NULL; - unsigned char *buf,*p; - int i, j; - - if (!no_name) { - if( ((nid = OBJ_sn2nid(s)) != NID_undef) || - ((nid = OBJ_ln2nid(s)) != NID_undef) ) - return OBJ_nid2obj(nid); - } - - // Work out size of content octets - i = a2d_ASN1_OBJECT(NULL,0,s,-1); - if (i <= 0) { - // Clear the error - ERR_get_error(); - return NULL; - } - // Work out total size - j = ASN1_object_size(0,i,V_ASN1_OBJECT); - - if ((buf=(unsigned char *)OPENSSL_malloc(j)) == NULL) return NULL; - - p = buf; - // Write out tag+length - ASN1_put_object(&p,0,i,V_ASN1_OBJECT,V_ASN1_UNIVERSAL); - // Write out contents - a2d_ASN1_OBJECT(p,i,s,-1); - - p = buf; -#if OPENSSL_VERSION_NUMBER >= 0x0090800f - // not op=d2i_ASN1_OBJECT(0, &p, i) (C.H. Christensen, Oct 12, 2005) - op = d2i_ASN1_OBJECT(0, (XRDGSI_CONST unsigned char**)(&p), j); -#else - op = d2i_ASN1_OBJECT(0, &p, i); -#endif - OPENSSL_free(buf); - return op; -} -// ------------------------------------------------------------------------- - -// -// Functions to create and destroy a gsiProxyPolicy_t -// (NB: the names of the internal variables a fixed by the ASN1 macros) -// -//___________________________________________________________________________ -gsiProxyPolicy_t *gsiProxyPolicy_new() -{ - // Create a new gsiProxyPolicy_t object - ASN1_CTX c; - gsiProxyPolicy_t *ret; - - // Init object - ret = 0; - M_ASN1_New_Malloc(ret, gsiProxyPolicy_t); - // Fill default policy - ret->policyLanguage = OBJ_txt2obj_fix("1.3.6.1.5.5.7.21.1", 1); - ret->policy = 0; - // Return ok - return (ret); - // Error: flag it - M_ASN1_New_Error(ASN1_F_GSIPROXYPOLICY_NEW); -} - -//___________________________________________________________________________ -void gsiProxyPolicy_free(gsiProxyPolicy_t *pol) -{ - // Free a gsiProxyPolicy_t object - - // Make sure there is something to free - if (!pol) - return; - // - // Free language object - if (pol->policyLanguage) - ASN1_OBJECT_free(pol->policyLanguage); - // - // Free policy octet string - if (pol->policy) - M_ASN1_OCTET_STRING_free(pol->policy); - // - // Free the container - OPENSSL_free(pol); -} - -// -// This function allows to convert the internal representation to a -// gsiProxyPolicy_t object. We need this for correct parsing of a -// ProxyCertInfo object, even if we are not presently interested -// in the policy. -//___________________________________________________________________________ -gsiProxyPolicy_t *d2i_gsiProxyPolicy(gsiProxyPolicy_t **pol, - XRDGSI_CONST unsigned char **pp, long length) -{ - // Get the policy object from buffer at pp, of length bytes. - - // Define vars - M_ASN1_D2I_vars(pol, gsiProxyPolicy_t *, gsiProxyPolicy_new); - // - // Init sequence - M_ASN1_D2I_Init(); - M_ASN1_D2I_start_sequence(); - // - // Retrieve language - M_ASN1_D2I_get(ret->policyLanguage, d2i_ASN1_OBJECT); - // - // Retrieve content - M_ASN1_D2I_get_IMP_opt(ret->policy, d2i_ASN1_OCTET_STRING, - 0, V_ASN1_OCTET_STRING); - // - // Finalize - M_ASN1_D2I_Finish(pol, gsiProxyPolicy_free, ASN1_F_D2I_GSIPROXYPOLICY); -} -// -// This function allows to convert a gsiProxyPolicy_t object to -// internal representation. We need this for correct updating of -// the path length in a ProxyCertInfo object, even if we are not -// presently interested in the policy. -//___________________________________________________________________________ -int i2d_gsiProxyPolicy(gsiProxyPolicy_t *pol, unsigned char **pp) +ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION_OLD) = { - // Set the policy object from pol to buffer at pp. - // Return number of meningful bytes + ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION, proxyPolicy, PROXY_POLICY), + ASN1_EXP_OPT(PROXY_CERT_INFO_EXTENSION, pcPathLengthConstraint, ASN1_INTEGER, 1) +} ASN1_SEQUENCE_END_name(PROXY_CERT_INFO_EXTENSION, PROXY_CERT_INFO_EXTENSION_OLD) - // Define vars - M_ASN1_I2D_vars(pol); - // - // Set language length - M_ASN1_I2D_len(pol->policyLanguage, i2d_ASN1_OBJECT); - // - // Set content length - if (pol->policy) { - M_ASN1_I2D_len(pol->policy, i2d_ASN1_OCTET_STRING); - } - // - // Sequence - M_ASN1_I2D_seq_total(); - // - // Set language - M_ASN1_I2D_put(pol->policyLanguage, i2d_ASN1_OBJECT); - // - // Set content - if (pol->policy) { - M_ASN1_I2D_put(pol->policy, i2d_ASN1_OCTET_STRING); - } - // - // Finalize - M_ASN1_I2D_finish(); -} -// -// Functions to create and destroy a gsiProxyCertInfo_t -// -//___________________________________________________________________________ -gsiProxyCertInfo_t *gsiProxyCertInfo_new() -{ - // Create a new gsiProxyCertInfo_t object - ASN1_CTX c; - gsiProxyCertInfo_t *ret; - // - // Init object - ret = 0; - M_ASN1_New_Malloc(ret, gsiProxyCertInfo_t); - memset(ret, 0, sizeof(gsiProxyCertInfo_t)); - // - // Default values - ret->proxyCertPathLengthConstraint = 0; - ret->proxyPolicy = gsiProxyPolicy_new(); - // - // Return OK - return (ret); - // - // Error: flag it - M_ASN1_New_Error(ASN1_F_GSIPROXYCERTINFO_NEW); -} - -//___________________________________________________________________________ -void gsiProxyCertInfo_free(gsiProxyCertInfo_t *pci) -{ - // Free a gsiProxyPolicy_t object - - // Make sure there is something to free - if (!pci) - return; - // Free path len constraint object - if (pci->proxyCertPathLengthConstraint) - ASN1_INTEGER_free(pci->proxyCertPathLengthConstraint); - // Free the container - OPENSSL_free(pci); -} - -// -// This function allow to convert the internal representation to a -// gsiProxyCertInfo_t object. -//___________________________________________________________________________ -gsiProxyCertInfo_t *d2i_gsiProxyCertInfo(gsiProxyCertInfo_t **pci, - XRDGSI_CONST unsigned char **pp, long length) -{ - // Get the proxy certificate info object from length bytes at pp. - - // Define vars - M_ASN1_D2I_vars(pci, gsiProxyCertInfo_t *, gsiProxyCertInfo_new); - // - // Init sequence - M_ASN1_D2I_Init(); - M_ASN1_D2I_start_sequence(); - // - // Retrieve the policy (wee need to do this to avoid screwing - // up the sequence pointers) - M_ASN1_D2I_get(ret->proxyPolicy, d2i_gsiProxyPolicy); - // - // Retrieve the path length constraint - M_ASN1_D2I_get_EXP_opt(ret->proxyCertPathLengthConstraint, d2i_ASN1_INTEGER, 1); - M_ASN1_D2I_get_opt(ret->proxyCertPathLengthConstraint, d2i_ASN1_INTEGER, - V_ASN1_INTEGER); - // - // Finalize - M_ASN1_D2I_Finish(pci, gsiProxyCertInfo_free, ASN1_F_D2I_GSIPROXYCERTINFO); -} -// -// This function allows to convert a gsiProxyCertInfo_t object to -// internal representation. -//___________________________________________________________________________ -int i2d_gsiProxyCertInfo(gsiProxyCertInfo_t *pci, unsigned char **pp) -{ - // Set the proxy certificate info object from pol to buffer at pp. - // Return number of meningful bytes - int v1 = 0; - - // Define vars - M_ASN1_I2D_vars(pci); - v1 = 0; - // - // Set length of proxyPolicy - M_ASN1_I2D_len(pci->proxyPolicy, i2d_gsiProxyPolicy); - // - // Set len of the path length constraint field - if (pci->proxyCertPathLengthConstraint) { - M_ASN1_I2D_len_EXP_opt(pci->proxyCertPathLengthConstraint, - i2d_ASN1_INTEGER, 1, v1); - } - // - // Sequence - M_ASN1_I2D_seq_total(); - // - // Set policy - M_ASN1_I2D_put(pci->proxyPolicy, i2d_gsiProxyPolicy); - // - // Set path length constraint - if (pci->proxyCertPathLengthConstraint) { - M_ASN1_I2D_put_EXP_opt(pci->proxyCertPathLengthConstraint, i2d_ASN1_INTEGER, 1, v1); - } - // - // Finalize - M_ASN1_I2D_finish(); -} -//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(PROXY_CERT_INFO_EXTENSION, PROXY_CERT_INFO_EXTENSION_OLD, PROXY_CERT_INFO_EXTENSION_OLD) //___________________________________________________________________________ bool XrdCryptosslProxyCertInfo(const void *extdata, int &pathlen, bool *haspolicy) @@ -420,25 +154,25 @@ bool XrdCryptosslProxyCertInfo(const void *extdata, int &pathlen, bool *haspolic // Check ProxyCertInfo OID char s[80] = {0}; OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(ext), 1); - if (strcmp(s, gsiProxyCertInfo_OID)) { - return 0; - } // Now extract the path length constraint, if any - unsigned char *p = ext->value->data; - gsiProxyCertInfo_t *pci = - d2i_gsiProxyCertInfo(0, (XRDGSI_CONST unsigned char **)(&p), ext->value->length); + unsigned char *p = X509_EXTENSION_get_data(ext)->data; + PROXY_CERT_INFO_EXTENSION *pci = 0; + if (!strcmp(s, gsiProxyCertInfo_OID)) + pci = d2i_PROXY_CERT_INFO_EXTENSION(0, (XRDGSI_CONST unsigned char **)(&p), X509_EXTENSION_get_data(ext)->length); + else if (!strcmp(s, gsiProxyCertInfo_OLD_OID)) + pci = d2i_PROXY_CERT_INFO_EXTENSION_OLD(0, (XRDGSI_CONST unsigned char **)(&p), X509_EXTENSION_get_data(ext)->length); if (!pci) { return 0; } // Default length is -1, i.e. check disabled pathlen = -1; - if (pci->proxyCertPathLengthConstraint) { - pathlen = ASN1_INTEGER_get(pci->proxyCertPathLengthConstraint); + if (pci->pcPathLengthConstraint) { + pathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint); } - // If required, check te existence of a policy field + // If required, check the existence of a policy field if (haspolicy) { *haspolicy = (pci->proxyPolicy) ? 1 : 0; } @@ -463,19 +197,20 @@ void XrdCryptosslSetPathLenConstraint(void *extdata, int pathlen) // Check ProxyCertInfo OID char s[80] = {0}; OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(ext), 1); - if (strcmp(s, gsiProxyCertInfo_OID)) - return; // Now extract the path length constraint, if any - unsigned char *p = ext->value->data; - gsiProxyCertInfo_t *pci = - d2i_gsiProxyCertInfo(0, (XRDGSI_CONST unsigned char **)(&p), ext->value->length); + unsigned char *p = X509_EXTENSION_get_data(ext)->data; + PROXY_CERT_INFO_EXTENSION *pci = 0; + if (!strcmp(s, gsiProxyCertInfo_OID)) + pci = d2i_PROXY_CERT_INFO_EXTENSION(0, (XRDGSI_CONST unsigned char **)(&p), X509_EXTENSION_get_data(ext)->length); + else if (!strcmp(s, gsiProxyCertInfo_OLD_OID)) + pci = d2i_PROXY_CERT_INFO_EXTENSION_OLD(0, (XRDGSI_CONST unsigned char **)(&p), X509_EXTENSION_get_data(ext)->length); if (!pci) return; // Set the new length - if (pci->proxyCertPathLengthConstraint) { - ASN1_INTEGER_set(pci->proxyCertPathLengthConstraint, pathlen); + if (pci->pcPathLengthConstraint) { + ASN1_INTEGER_set(pci->pcPathLengthConstraint, pathlen); } // We are done @@ -483,7 +218,7 @@ void XrdCryptosslSetPathLenConstraint(void *extdata, int pathlen) } //____________________________________________________________________________ -int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk, +int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk, XrdProxyOpt_t *pxopt, XrdCryptogsiX509Chain *xp, XrdCryptoRSA **kp, const char *fnp) @@ -493,7 +228,7 @@ int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk, // A chain containing the proxy certificate and the EEC is returned in 'xp' // and its full RSA key in 'kp'. // The structure pxopt can be used to change the default options about - // number of bits for teh key, duration validity and max path signature depth. + // number of bits for the key, duration validity and max path signature depth. // If 'fpn' is defined, a PEM file is created with, in order, the proxy // certificate, the related private key and the EEC certificate (standard // GSI format). @@ -532,14 +267,15 @@ int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk, return -kErrPX_BadEECfile; } } else { - PRINT("EEC certificate cannot be opened (file: "< XrdCryptosslASN1toUTC(X509_get_notAfter(xEEC))) { - PRINT("EEC certificate has expired"); + PRINT("EEC certificate has expired"); + X509_free(xEEC); return -kErrPX_ExpiredEEC; } @@ -552,21 +288,25 @@ int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk, XrdOucString sbj; XrdCryptosslNameOneLine(X509_get_subject_name(xEEC), sbj); PRINT("Your identity: "<pkey.rsa) == 0)) { + if ((RSA_check_key(EVP_PKEY_get0_RSA(ekEEC)) == 0)) { PRINT("inconsistent key loaded"); + EVP_PKEY_free(ekEEC); + X509_free(xEEC); return -kErrPX_BadEECkey; } // @@ -574,25 +314,50 @@ int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk, X509_REQ *preq = X509_REQ_new(); if (!preq) { PRINT("cannot to create cert request"); + EVP_PKEY_free(ekEEC); + X509_free(xEEC); return -kErrPX_NoResources; } // // Create the new PKI for the proxy (exponent 65537) - RSA *kPX = RSA_generate_key(bits, 0x10001, 0, 0); + RSA *kPX = RSA_new(); if (!kPX) { - PRINT("proxy key could not be generated - return"); + PRINT("proxy key could not be generated - return"); + EVP_PKEY_free(ekEEC); + X509_free(xEEC); + return -kErrPX_GenerateKey; + } + BIGNUM *e = BN_new(); + if (!e) { + PRINT("proxy key could not be generated - return"); + RSA_free(kPX); + EVP_PKEY_free(ekEEC); + X509_free(xEEC); return -kErrPX_GenerateKey; } + BN_set_word(e, 0x10001); + if (RSA_generate_key_ex(kPX, bits, e, NULL) != 1) { + PRINT("proxy key could not be generated - return"); + BN_free(e); + RSA_free(kPX); + EVP_PKEY_free(ekEEC); + X509_free(xEEC); + return -kErrPX_GenerateKey; + } + BN_free(e); // // Set the key into the request EVP_PKEY *ekPX = EVP_PKEY_new(); if (!ekPX) { - PRINT("could not create a EVP_PKEY * instance - return"); + PRINT("could not create a EVP_PKEY * instance - return"); + RSA_free(kPX); + EVP_PKEY_free(ekEEC); + X509_free(xEEC); return -kErrPX_NoResources; } - EVP_PKEY_set1_RSA(ekPX, kPX); + EVP_PKEY_assign_RSA(ekPX, kPX); X509_REQ_set_pubkey(preq, ekPX); - // + // // Generate a serial number. Specification says that this *should* // unique, so we just draw an unsigned random integer unsigned int serial = XrdSutRndm::GetUInt(); @@ -601,34 +366,36 @@ int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk, // with is a random unsigned int used also as serial // number. // Duplicate user subject name - X509_NAME *psubj = X509_NAME_dup(X509_get_subject_name(xEEC)); + X509_NAME *psubj = X509_NAME_dup(X509_get_subject_name(xEEC)); // Create an entry with the common name unsigned char sn[20] = {0}; sprintf((char *)sn, "%d", serial); if (!X509_NAME_add_entry_by_txt(psubj, (char *)"CN", MBSTRING_ASC, sn, -1, -1, 0)) { - PRINT("could not add CN - (serial: "<proxyPolicy->policyLanguage = OBJ_txt2obj("1.3.6.1.5.5.7.21.1", 1); + // // Set the new length if (depthlen > -1) { - if ((pci->proxyCertPathLengthConstraint = ASN1_INTEGER_new())) { - ASN1_INTEGER_set(pci->proxyCertPathLengthConstraint, depthlen); + if ((pci->pcPathLengthConstraint = ASN1_INTEGER_new())) { + ASN1_INTEGER_set(pci->pcPathLengthConstraint, depthlen); } else { - PRINT("could not set the path length contrain"); + PRINT("could not set the path length contrain"); return -kErrPX_SetPathDepth; } } @@ -637,110 +404,101 @@ int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk, // create extension X509_EXTENSION *ext = X509_EXTENSION_new(); if (!ext) { - PRINT("could not create extension object"); + PRINT("could not create extension object"); return -kErrPX_NoResources; } // Set extension name. -#if OPENSSL_VERSION_NUMBER >= 0x0090700f - // We do not use directly OBJ_txt2obj because that is not working - // with all OpenSSL 0.9.6 versions - ASN1_OBJECT *obj = OBJ_nid2obj(OBJ_create(gsiProxyCertInfo_OID, - "gsiProxyCertInfo_OID","GSI ProxyCertInfo OID")); -#else - // This version of OBJ_txt2obj fixes a bug affecting some - // OpenSSL 0.9.6 versions - ASN1_OBJECT *obj = OBJ_txt2obj_fix(gsiProxyCertInfo_OID, 1); -#endif + ASN1_OBJECT *obj = OBJ_txt2obj(gsiProxyCertInfo_OID, 1); if (!obj || X509_EXTENSION_set_object(ext, obj) != 1) { - PRINT("could not set extension name"); + PRINT("could not set extension name"); return -kErrPX_SetAttribute; } // flag as critical if (X509_EXTENSION_set_critical(ext, 1) != 1) { - PRINT("could not set extension critical flag"); + PRINT("could not set extension critical flag"); return -kErrPX_SetAttribute; } // Extract data in format for extension - ext->value->length = i2d_gsiProxyCertInfo(pci, 0); - if (!(ext->value->data = (unsigned char *)malloc(ext->value->length+1))) { - PRINT("could not allocate data field for extension"); + X509_EXTENSION_get_data(ext)->length = i2d_PROXY_CERT_INFO_EXTENSION(pci, 0); + if (!(X509_EXTENSION_get_data(ext)->data = (unsigned char *)malloc(X509_EXTENSION_get_data(ext)->length+1))) { + PRINT("could not allocate data field for extension"); return -kErrPX_NoResources; } - unsigned char *pp = ext->value->data; - if ((i2d_gsiProxyCertInfo(pci, &pp)) <= 0) { - PRINT("problem converting data for extension"); + unsigned char *pp = X509_EXTENSION_get_data(ext)->data; + if ((i2d_PROXY_CERT_INFO_EXTENSION(pci, &pp)) <= 0) { + PRINT("problem converting data for extension"); return -kErrPX_Error; } // Create a stack STACK_OF(X509_EXTENSION) *esk = sk_X509_EXTENSION_new_null(); if (!esk) { - PRINT("could not create stack for extensions"); + PRINT("could not create stack for extensions"); return -kErrPX_NoResources; } // // Now we add the new extension if (sk_X509_EXTENSION_push(esk, ext) == 0) { - PRINT("could not push the extension in the stack"); + PRINT("could not push the extension in the stack"); return -kErrPX_Error; } // Add extension if (!(X509_REQ_add_extensions(preq, esk))) { - PRINT("problem adding extension"); + PRINT("problem adding extension"); return -kErrPX_SetAttribute; } // // Sign the request - if (!(X509_REQ_sign(preq, ekPX, EVP_md5()))) { - PRINT("problems signing the request"); + if (!(X509_REQ_sign(preq, ekPX, EVP_sha1()))) { + PRINT("problems signing the request"); return -kErrPX_Signing; } // // Create new proxy cert X509 *xPX = X509_new(); if (!xPX) { - PRINT("could not create certificate object for proxies"); + PRINT("could not create certificate object for proxies"); return -kErrPX_NoResources; } // Set version number if (X509_set_version(xPX, 2L) != 1) { - PRINT("could not set version"); + PRINT("could not set version"); return -kErrPX_SetAttribute; } // Set serial number if (ASN1_INTEGER_set(X509_get_serialNumber(xPX), serial) != 1) { - PRINT("could not set serial number"); + PRINT("could not set serial number"); return -kErrPX_SetAttribute; } // Set subject name if (X509_set_subject_name(xPX, psubj) != 1) { - PRINT("could not set subject name"); + PRINT("could not set subject name"); return -kErrPX_SetAttribute; } - + // Set issuer name if (X509_set_issuer_name(xPX, X509_get_subject_name(xEEC)) != 1) { - PRINT("could not set issuer name"); + PRINT("could not set issuer name"); return -kErrPX_SetAttribute; } // Set public key if (X509_set_pubkey(xPX, ekPX) != 1) { - PRINT("could not set issuer name"); + PRINT("could not set issuer name"); return -kErrPX_SetAttribute; } // Set proxy validity: notBefore now if (!X509_gmtime_adj(X509_get_notBefore(xPX), 0)) { - PRINT("could not set notBefore"); + PRINT("could not set notBefore"); return -kErrPX_SetAttribute; } // Set proxy validity: notAfter expire_secs from now if (!X509_gmtime_adj(X509_get_notAfter(xPX), valid)) { - PRINT("could not set notAfter"); + PRINT("could not set notAfter"); return -kErrPX_SetAttribute; } @@ -761,7 +519,7 @@ int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk, // Duplicate and add to the stack X509_EXTENSION *xEECextdup = X509_EXTENSION_dup(xEECext); if (X509_add_ext(xPX, xEECextdup, -1) == 0) { - PRINT("could not push the extension '"<PushBack(xcPX); XrdCryptoX509 *xcEEC = new XrdCryptosslX509(xEEC); if (!xcEEC) { - PRINT("could not create container for EEC certificate"); + PRINT("could not create container for EEC certificate"); return -kErrPX_NoResources; } xp->PushBack(xcEEC); *kp = new XrdCryptosslRSA(ekPX); if (!(*kp)) { - PRINT("could not creatr out PKI"); + PRINT("could not creatr out PKI"); return -kErrPX_NoResources; } - + // // Write to a file if requested int rc = 0; @@ -816,39 +574,39 @@ int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk, // Open the file in write mode FILE *fp = fopen(fnp,"w"); if (!fp) { - PRINT("cannot open file to save the proxy certificate (file: "<Opaque())) { PRINT("input proxy certificate not specified"); return -1; @@ -888,7 +646,7 @@ int XrdCryptosslX509CreateProxyReq(XrdCryptoX509 *xcpi, // Make sure the certificate is not expired if (!(xcpi->IsValid())) { - PRINT("EEC certificate has expired"); + PRINT("EEC certificate has expired"); return -kErrPX_ExpiredEEC; } // @@ -905,21 +663,35 @@ int XrdCryptosslX509CreateProxyReq(XrdCryptoX509 *xcpi, bits = (bits < 512) ? 512 : bits; // // Create the new PKI for the proxy (exponent 65537) - RSA *kro = RSA_generate_key(bits, 0x10001, 0, 0); + RSA *kro = RSA_new(); if (!kro) { - PRINT("proxy key could not be generated - return"); + PRINT("proxy key could not be generated - return"); return -kErrPX_GenerateKey; } + BIGNUM *e = BN_new(); + if (!e) { + PRINT("proxy key could not be generated - return"); + RSA_free(kro); + return -kErrPX_GenerateKey; + } + BN_set_word(e, 0x10001); + if (RSA_generate_key_ex(kro, bits, e, NULL) != 1) { + RSA_free(kro); + BN_free(e); + PRINT("proxy key could not be generated - return"); + return -kErrPX_GenerateKey; + } + BN_free(e); // // Set the key into the request EVP_PKEY *ekro = EVP_PKEY_new(); if (!ekro) { - PRINT("could not create a EVP_PKEY * instance - return"); + PRINT("could not create a EVP_PKEY * instance - return"); return -kErrPX_NoResources; } - EVP_PKEY_set1_RSA(ekro, kro); + EVP_PKEY_assign_RSA(ekro, kro); X509_REQ_set_pubkey(xro, ekro); - // + // // Generate a serial number. Specification says that this *should* // unique, so we just draw an unsigned random integer unsigned int serial = XrdSutRndm::GetUInt(); @@ -928,11 +700,11 @@ int XrdCryptosslX509CreateProxyReq(XrdCryptoX509 *xcpi, // with is a random unsigned int used also as serial // number. // Duplicate user subject name - X509_NAME *psubj = X509_NAME_dup(X509_get_subject_name(xpi)); + X509_NAME *psubj = X509_NAME_dup(X509_get_subject_name(xpi)); if (xcro && *xcro && *((int *)(*xcro)) <= 10100) { // Delete existing proxy CN addition; for backward compatibility #if OPENSSL_VERSION_NUMBER >= 0x10000000L - int ne = sk_X509_NAME_ENTRY_num(psubj->entries); + int ne = X509_NAME_entry_count(psubj); #else /* OPENSSL */ int ne = psubj->entries->num; #endif /* OPENSSL */ @@ -951,27 +723,28 @@ int XrdCryptosslX509CreateProxyReq(XrdCryptoX509 *xcpi, sprintf((char *)sn, "%d", serial); if (!X509_NAME_add_entry_by_txt(psubj, (char *)"CN", MBSTRING_ASC, sn, -1, -1, 0)) { - PRINT("could not add CN - (serial: "<proxyPolicy->policyLanguage = OBJ_txt2obj("1.3.6.1.5.5.7.21.1", 1); // // Create a stack STACK_OF(X509_EXTENSION) *esk = sk_X509_EXTENSION_new_null(); if (!esk) { - PRINT("could not create stack for extensions"); + PRINT("could not create stack for extensions"); return -kErrPX_NoResources; } // @@ -990,19 +763,23 @@ int XrdCryptosslX509CreateProxyReq(XrdCryptoX509 *xcpi, // Skip subject alternative name extension if (!strcmp(s, SUBJ_ALT_NAME_OID)) continue; // Get signature path depth from present proxy - if (!strcmp(s, gsiProxyCertInfo_OID)) { - unsigned char *p = xpiext->value->data; - gsiProxyCertInfo_t *inpci = - d2i_gsiProxyCertInfo(0, (XRDGSI_CONST unsigned char **)(&p), xpiext->value->length); - if (inpci && - inpci->proxyCertPathLengthConstraint) - indepthlen = ASN1_INTEGER_get(inpci->proxyCertPathLengthConstraint); + if (!strcmp(s, gsiProxyCertInfo_OID) || + !strcmp(s, gsiProxyCertInfo_OLD_OID)) { + unsigned char *p = X509_EXTENSION_get_data(xpiext)->data; + PROXY_CERT_INFO_EXTENSION *inpci = 0; + if (!strcmp(s, gsiProxyCertInfo_OID)) + inpci = d2i_PROXY_CERT_INFO_EXTENSION(0, (XRDGSI_CONST unsigned char **)(&p), X509_EXTENSION_get_data(xpiext)->length); + else + inpci = d2i_PROXY_CERT_INFO_EXTENSION_OLD(0, (XRDGSI_CONST unsigned char **)(&p), X509_EXTENSION_get_data(xpiext)->length); + if (inpci && + inpci->pcPathLengthConstraint) + indepthlen = ASN1_INTEGER_get(inpci->pcPathLengthConstraint); DEBUG("IN depth length: "< -1) { - if ((pci->proxyCertPathLengthConstraint = ASN1_INTEGER_new())) { + if ((pci->pcPathLengthConstraint = ASN1_INTEGER_new())) { int depthlen = (indepthlen > 0) ? (indepthlen-1) : 0; - ASN1_INTEGER_set(pci->proxyCertPathLengthConstraint, depthlen); + ASN1_INTEGER_set(pci->pcPathLengthConstraint, depthlen); } else { - PRINT("could not set the path length contrain"); + PRINT("could not set the path length contrain"); return -kErrPX_SetPathDepth; } } @@ -1033,53 +810,44 @@ int XrdCryptosslX509CreateProxyReq(XrdCryptoX509 *xcpi, // create extension X509_EXTENSION *ext = X509_EXTENSION_new(); if (!ext) { - PRINT("could not create extension object"); + PRINT("could not create extension object"); return -kErrPX_NoResources; } // Extract data in format for extension - ext->value->length = i2d_gsiProxyCertInfo(pci, 0); - if (!(ext->value->data = (unsigned char *)malloc(ext->value->length+1))) { - PRINT("could not allocate data field for extension"); + X509_EXTENSION_get_data(ext)->length = i2d_PROXY_CERT_INFO_EXTENSION(pci, 0); + if (!(X509_EXTENSION_get_data(ext)->data = (unsigned char *)malloc(X509_EXTENSION_get_data(ext)->length+1))) { + PRINT("could not allocate data field for extension"); return -kErrPX_NoResources; } - unsigned char *pp = ext->value->data; - if ((i2d_gsiProxyCertInfo(pci, &pp)) <= 0) { - PRINT("problem converting data for extension"); + unsigned char *pp = X509_EXTENSION_get_data(ext)->data; + if ((i2d_PROXY_CERT_INFO_EXTENSION(pci, &pp)) <= 0) { + PRINT("problem converting data for extension"); return -kErrPX_Error; } // Set extension name. -#if OPENSSL_VERSION_NUMBER >= 0x0090700f - // We do not use directly OBJ_txt2obj because that is not working - // with all OpenSSL 0.9.6 versions - ASN1_OBJECT *obj = OBJ_nid2obj(OBJ_create(gsiProxyCertInfo_OID, - "gsiProxyCertInfo_OID","GSI ProxyCertInfo OID")); -#else - // This version of OBJ_txt2obj fixes a bug affecting some - // OpenSSL 0.9.6 versions - ASN1_OBJECT *obj = OBJ_txt2obj_fix(gsiProxyCertInfo_OID, 1); -#endif + ASN1_OBJECT *obj = OBJ_txt2obj(gsiProxyCertInfo_OID, 1); if (!obj || X509_EXTENSION_set_object(ext, obj) != 1) { - PRINT("could not set extension name"); + PRINT("could not set extension name"); return -kErrPX_SetAttribute; } // flag as critical if (X509_EXTENSION_set_critical(ext, 1) != 1) { - PRINT("could not set extension critical flag"); + PRINT("could not set extension critical flag"); return -kErrPX_SetAttribute; } if (sk_X509_EXTENSION_push(esk, ext) == 0) { - PRINT("could not push the extension in the stack"); + PRINT("could not push the extension in the stack"); return -kErrPX_Error; } // Add extensions if (!(X509_REQ_add_extensions(xro, esk))) { - PRINT("problem adding extension"); + PRINT("problem adding extension"); return -kErrPX_SetAttribute; } // // Sign the request - if (!(X509_REQ_sign(xro, ekro, EVP_md5()))) { - PRINT("problems signing the request"); + if (!(X509_REQ_sign(xro, ekro, EVP_sha1()))) { + PRINT("problems signing the request"); return -kErrPX_Signing; } @@ -1116,7 +884,7 @@ int XrdCryptosslX509SignProxyReq(XrdCryptoX509 *xcpi, XrdCryptoRSA *kcpi, // Make sure the certificate is not expired int timeleft = xcpi->NotAfter() - (int)time(0) + XrdCryptoTZCorr(); if (timeleft < 0) { - PRINT("EEC certificate has expired"); + PRINT("EEC certificate has expired"); return -kErrPX_ExpiredEEC; } // Point to the cerificate @@ -1128,12 +896,12 @@ int XrdCryptosslX509SignProxyReq(XrdCryptoX509 *xcpi, XrdCryptoRSA *kcpi, return -kErrPX_BadEECkey; } // Point to the cerificate - RSA *kpi = ((EVP_PKEY *)(kcpi->Opaque()))->pkey.rsa; + RSA *kpi = EVP_PKEY_get0_RSA((EVP_PKEY *)(kcpi->Opaque())); // // Set the key into the request EVP_PKEY *ekpi = EVP_PKEY_new(); if (!ekpi) { - PRINT("could not create a EVP_PKEY * instance - return"); + PRINT("could not create a EVP_PKEY * instance - return"); return -kErrPX_NoResources; } EVP_PKEY_set1_RSA(ekpi, kpi); @@ -1181,49 +949,49 @@ int XrdCryptosslX509SignProxyReq(XrdCryptoX509 *xcpi, XrdCryptoRSA *kcpi, // Create new proxy cert X509 *xpo = X509_new(); if (!xpo) { - PRINT("could not create certificate object for proxies"); + PRINT("could not create certificate object for proxies"); return -kErrPX_NoResources; } // Set version number if (X509_set_version(xpo, 2L) != 1) { - PRINT("could not set version"); + PRINT("could not set version"); return -kErrPX_SetAttribute; } // Set serial number if (ASN1_INTEGER_set(X509_get_serialNumber(xpo), serial) != 1) { - PRINT("could not set serial number"); + PRINT("could not set serial number"); return -kErrPX_SetAttribute; } // Set subject name if (X509_set_subject_name(xpo, X509_REQ_get_subject_name(xri)) != 1) { - PRINT("could not set subject name"); + PRINT("could not set subject name"); return -kErrPX_SetAttribute; } - + // Set issuer name if (X509_set_issuer_name(xpo, X509_get_subject_name(xpi)) != 1) { - PRINT("could not set issuer name"); + PRINT("could not set issuer name"); return -kErrPX_SetAttribute; } // Set public key if (X509_set_pubkey(xpo, X509_REQ_get_pubkey(xri)) != 1) { - PRINT("could not set public key"); + PRINT("could not set public key"); return -kErrPX_SetAttribute; } // Set proxy validity: notBefore now if (!X509_gmtime_adj(X509_get_notBefore(xpo), 0)) { - PRINT("could not set notBefore"); + PRINT("could not set notBefore"); return -kErrPX_SetAttribute; } // Set proxy validity: notAfter timeleft from now if (!X509_gmtime_adj(X509_get_notAfter(xpo), timeleft)) { - PRINT("could not set notAfter"); + PRINT("could not set notAfter"); return -kErrPX_SetAttribute; } @@ -1238,28 +1006,33 @@ int XrdCryptosslX509SignProxyReq(XrdCryptoX509 *xcpi, XrdCryptoRSA *kcpi, xpiext = X509_get_ext(xpi, i); char s[256] = {0}; ASN1_OBJECT *obj = X509_EXTENSION_get_object(xpiext); - if (obj) + if (obj) OBJ_obj2txt(s, sizeof(s), obj, 1); - if (!strcmp(s, gsiProxyCertInfo_OID)) { - unsigned char *p = xpiext->value->data; - gsiProxyCertInfo_t *inpci = - d2i_gsiProxyCertInfo(0, (XRDGSI_CONST unsigned char **)(&p), xpiext->value->length); - if (inpci && - inpci->proxyCertPathLengthConstraint) - indepthlen = ASN1_INTEGER_get(inpci->proxyCertPathLengthConstraint); + if (!strcmp(s, gsiProxyCertInfo_OID) || + !strcmp(s, gsiProxyCertInfo_OLD_OID)) { + unsigned char *p = X509_EXTENSION_get_data(xpiext)->data; + PROXY_CERT_INFO_EXTENSION *inpci = 0; + if (!strcmp(s, gsiProxyCertInfo_OID)) + inpci = d2i_PROXY_CERT_INFO_EXTENSION(0, (XRDGSI_CONST unsigned char **)(&p), X509_EXTENSION_get_data(xpiext)->length); + else + inpci = d2i_PROXY_CERT_INFO_EXTENSION_OLD(0, (XRDGSI_CONST unsigned char **)(&p), X509_EXTENSION_get_data(xpiext)->length); + if (inpci && + inpci->pcPathLengthConstraint) + indepthlen = ASN1_INTEGER_get(inpci->pcPathLengthConstraint); DEBUG("IN depth length: "<value->data; - gsiProxyCertInfo_t *reqpci = - d2i_gsiProxyCertInfo(0, (XRDGSI_CONST unsigned char **)(&p), xriext->value->length); + unsigned char *p = X509_EXTENSION_get_data(xriext)->data; + PROXY_CERT_INFO_EXTENSION *reqpci = + d2i_PROXY_CERT_INFO_EXTENSION(0, (XRDGSI_CONST unsigned char **)(&p), X509_EXTENSION_get_data(xriext)->length); if (reqpci && - reqpci->proxyCertPathLengthConstraint) - reqdepthlen = ASN1_INTEGER_get(reqpci->proxyCertPathLengthConstraint); + reqpci->pcPathLengthConstraint) + reqdepthlen = ASN1_INTEGER_get(reqpci->pcPathLengthConstraint); DEBUG("REQ depth length: "<proxyPolicy->policyLanguage = OBJ_txt2obj("1.3.6.1.5.5.7.21.1", 1); + // // Set the new length if (outdepthlen > -1) { - if ((pci->proxyCertPathLengthConstraint = ASN1_INTEGER_new())) { + if ((pci->pcPathLengthConstraint = ASN1_INTEGER_new())) { int depthlen = (outdepthlen > 0) ? (outdepthlen-1) : 0; - ASN1_INTEGER_set(pci->proxyCertPathLengthConstraint, depthlen); + ASN1_INTEGER_set(pci->pcPathLengthConstraint, depthlen); } else { - PRINT("could not set the path length contrain"); + PRINT("could not set the path length contrain"); return -kErrPX_SetPathDepth; } } // create extension X509_EXTENSION *ext = X509_EXTENSION_new(); if (!ext) { - PRINT("could not create extension object"); + PRINT("could not create extension object"); return -kErrPX_NoResources; } // Extract data in format for extension - ext->value->length = i2d_gsiProxyCertInfo(pci, 0); - if (!(ext->value->data = (unsigned char *)malloc(ext->value->length+1))) { - PRINT("could not allocate data field for extension"); + X509_EXTENSION_get_data(ext)->length = i2d_PROXY_CERT_INFO_EXTENSION(pci, 0); + if (!(X509_EXTENSION_get_data(ext)->data = (unsigned char *)malloc(X509_EXTENSION_get_data(ext)->length+1))) { + PRINT("could not allocate data field for extension"); return -kErrPX_NoResources; } - unsigned char *pp = ext->value->data; - if ((i2d_gsiProxyCertInfo(pci, &pp)) <= 0) { - PRINT("problem converting data for extension"); + unsigned char *pp = X509_EXTENSION_get_data(ext)->data; + if ((i2d_PROXY_CERT_INFO_EXTENSION(pci, &pp)) <= 0) { + PRINT("problem converting data for extension"); return -kErrPX_Error; } // Set extension name. -#if OPENSSL_VERSION_NUMBER >= 0x0090700f - // We do not use directly OBJ_txt2obj because that is not working - // with all OpenSSL 0.9.6 versions - ASN1_OBJECT *obj = OBJ_nid2obj(OBJ_create(gsiProxyCertInfo_OID, - "gsiProxyCertInfo_OID","GSI ProxyCertInfo OID")); -#else - // This version of OBJ_txt2obj fixes a bug affecting some - // OpenSSL 0.9.6 versions - ASN1_OBJECT *obj = OBJ_txt2obj_fix(gsiProxyCertInfo_OID, 1); -#endif + ASN1_OBJECT *obj = OBJ_txt2obj(gsiProxyCertInfo_OID, 1); if (!obj || X509_EXTENSION_set_object(ext, obj) != 1) { - PRINT("could not set extension name"); + PRINT("could not set extension name"); return -kErrPX_SetAttribute; } // flag as critical if (X509_EXTENSION_set_critical(ext, 1) != 1) { - PRINT("could not set extension critical flag"); + PRINT("could not set extension critical flag"); return -kErrPX_SetAttribute; } // Add the extension if (X509_add_ext(xpo, ext, -1) == 0) { - PRINT("could not add extension"); + PRINT("could not add extension"); return -kErrPX_SetAttribute; } // // Sign the certificate - if (!(X509_sign(xpo, ekpi, EVP_md5()))) { - PRINT("problems signing the certificate"); + if (!(X509_sign(xpo, ekpi, EVP_sha1()))) { + PRINT("problems signing the certificate"); return -kErrPX_Signing; } @@ -1403,7 +1168,7 @@ int XrdCryptosslX509GetVOMSAttr(XrdCryptoX509 *xcpi, XrdOucString &vat) PRINT("invalid inputs"); return rc; } - + // Point to the cerificate X509 *xpi = (X509 *)(xcpi->Opaque()); @@ -1422,8 +1187,8 @@ int XrdCryptosslX509GetVOMSAttr(XrdCryptoX509 *xcpi, XrdOucString &vat) if (strcmp(s, XRDGSI_VOMS_ACSEQ_OID)) continue; // This is the VOMS extension we are interested for rc = 0; - XRDGSI_CONST unsigned char *pp = (XRDGSI_CONST unsigned char *) xpiext->value->data; - long length = xpiext->value->length; + XRDGSI_CONST unsigned char *pp = (XRDGSI_CONST unsigned char *) X509_EXTENSION_get_data(xpiext)->data; + long length = X509_EXTENSION_get_data(xpiext)->length; int ret = XrdCryptosslX509FillVOMS(&pp, length, getvat, vat); DEBUG("ret: " << ret << " - vat: " << vat); } @@ -1437,7 +1202,7 @@ int XrdCryptosslX509FillVOMS(XRDGSI_CONST unsigned char **pp, long length, bool &getvat, XrdOucString &vat) { // Look recursively for the VOMS attributes - // Return 2 if found, 1 if to continue searching, 0 to stop + // Return 2 if found, 1 if to continue searching, 0 to stop EPNAME("X509FillVOMS"); XRDGSI_CONST unsigned char *p,*ep,*tot,*op,*opp; @@ -1502,7 +1267,7 @@ int XrdCryptosslX509FillVOMS(XRDGSI_CONST unsigned char **pp, XrdOucString objstr; BIO_GET_STRING(mem, objstr); // Looking for the right extension ... - if (objstr == XRDGSI_VOMS_ATCAP_OID || objstr == "idatcap") getvat = 1; + if (objstr == XRDGSI_VOMS_ATCAP_OID || objstr == "idatcap") getvat = 1; DEBUG("AOBJ:"<Opaque()); @@ -1577,32 +1342,42 @@ int XrdCryptosslX509CheckProxy3(XrdCryptoX509 *xcpi, XrdOucString &emsg) { TRACE(ALL,"certificate has "<data; + pci = d2i_PROXY_CERT_INFO_EXTENSION(0, (XRDGSI_CONST unsigned char **)(&p), X509_EXTENSION_get_data(ext)->length); + } else { + PRINT("WARNING: multiple proxyCertInfo extensions found: taking the first"); + } + } + else if (!strncmp(s, gsiProxyCertInfo_OLD_OID, sizeof(gsiProxyCertInfo_OLD_OID))) { + if (ext == 0) { + ext = xext; + // Now get the extension + unsigned char *p = X509_EXTENSION_get_data(ext)->data; + pci = d2i_PROXY_CERT_INFO_EXTENSION_OLD(0, (XRDGSI_CONST unsigned char **)(&p), X509_EXTENSION_get_data(ext)->length); } else { PRINT("WARNING: multiple proxyCertInfo extensions found: taking the first"); } } } if (!ext) { - emsg = "gsiProxyCertInfo_OID not found"; + emsg = "proxyCertInfo extension not found"; return -1; } - - // Now get the extension - unsigned char *p = ext->value->data; - gsiProxyCertInfo_t *pci = - d2i_gsiProxyCertInfo(0, (XRDGSI_CONST unsigned char **)(&p), ext->value->length); if (!pci) { - emsg = "gsiProxyCertInfo_OID could not be deserialized"; + emsg = "proxyCertInfo extension could not be deserialized"; return -1; } diff --git a/src/XrdCrypto/XrdCryptosslgsiAux.hh b/src/XrdCrypto/XrdCryptosslgsiAux.hh index bed781f5761..aac394370e3 100644 --- a/src/XrdCrypto/XrdCryptosslgsiAux.hh +++ b/src/XrdCrypto/XrdCryptosslgsiAux.hh @@ -39,7 +39,8 @@ #include "XrdOuc/XrdOucString.hh" // The OID of the extension -#define gsiProxyCertInfo_OID "1.3.6.1.4.1.3536.1.222" +#define gsiProxyCertInfo_OLD_OID "1.3.6.1.4.1.3536.1.222" +#define gsiProxyCertInfo_OID "1.3.6.1.5.5.7.1.14" // // Function to check presence of a proxyCertInfo and retrieve the path length diff --git a/src/XrdHttp/XrdHttpProtocol.cc b/src/XrdHttp/XrdHttpProtocol.cc index e4caebf2bd4..5fe4d751eab 100644 --- a/src/XrdHttp/XrdHttpProtocol.cc +++ b/src/XrdHttp/XrdHttpProtocol.cc @@ -85,7 +85,7 @@ char *XrdHttpProtocol::secretkey = 0; char *XrdHttpProtocol::gridmap = 0; XrdOucGMap *XrdHttpProtocol::servGMap = 0; // Grid mapping service - + int XrdHttpProtocol::sslverifydepth = 9; SSL_CTX *XrdHttpProtocol::sslctx = 0; BIO *XrdHttpProtocol::sslbio_err = 0; @@ -290,47 +290,47 @@ XrdProtocol *XrdHttpProtocol::Match(XrdLink *lp) { int XrdHttpProtocol::GetVOMSData(XrdLink *lp) { TRACEI(DEBUG, " Extracting auth info."); - + SecEntity.host = GetClientIPStr(); X509 *peer_cert; - + // No external plugin, hence we fill our XrdSec with what we can do here peer_cert = SSL_get_peer_certificate(ssl); TRACEI(DEBUG, " SSL_get_peer_certificate returned :" << peer_cert); ERR_print_errors(sslbio_err); - - if (peer_cert && peer_cert->name) { - + + if (peer_cert) { + // Add the original DN to the moninfo. Not sure if it makes sense to parametrize this or not. - SecEntity.moninfo = strdup(peer_cert->name); - + SecEntity.moninfo = X509_NAME_oneline(X509_get_subject_name(peer_cert), NULL, 0); + // Here we have the user DN, we try to translate it using the XrdSec functions and the gridmap if (SecEntity.name) free(SecEntity.name); - if (servGMap) { + if (servGMap) { SecEntity.name = (char *)malloc(128); - int e = servGMap->dn2user(peer_cert->name, SecEntity.name, 127, 0); + int e = servGMap->dn2user(SecEntity.moninfo, SecEntity.name, 127, 0); if ( !e ) { - TRACEI(DEBUG, " Mapping Username: " << peer_cert->name << " --> " << SecEntity.name); + TRACEI(DEBUG, " Mapping Username: " << SecEntity.moninfo << " --> " << SecEntity.name); } else { - TRACEI(ALL, " Mapping Username: " << peer_cert->name << " Failed. err: " << e); - strncpy(SecEntity.name, peer_cert->name, 127); + TRACEI(ALL, " Mapping Username: " << SecEntity.moninfo << " Failed. err: " << e); + strncpy(SecEntity.name, SecEntity.moninfo, 127); } } else { - SecEntity.name = strdup(peer_cert->name); + SecEntity.name = strdup(SecEntity.moninfo); } - + TRACEI(DEBUG, " Setting link name: " << SecEntity.name); lp->setID(SecEntity.name, 0); } else return 0; // Don't fail if no cert - + if (peer_cert) X509_free(peer_cert); - + // Invoke our instance of the Security exctractor plugin // This will fill the XrdSec thing with VOMS info, if VOMS is // installed. If we have no sec extractor then do nothing, just plain https @@ -338,13 +338,13 @@ int XrdHttpProtocol::GetVOMSData(XrdLink *lp) { if (secxtractor) { int r = secxtractor->GetSecData(lp, SecEntity, ssl); if (r) - TRACEI(ALL, " Certificate data extraction failed: " << peer_cert->name << " Failed. err: " << r); + TRACEI(ALL, " Certificate data extraction failed: " << SecEntity.moninfo << " Failed. err: " << r); return r; } - + return 0; } - + char *XrdHttpProtocol::GetClientIPStr() { char buf[256]; buf[0] = '\0'; @@ -410,7 +410,7 @@ int XrdHttpProtocol::Process(XrdLink *lp) // We ignore the argument here // maybe it wants to add its own initialization bits if (secxtractor) secxtractor->InitSSL(ssl, sslcadir); - + SSL_set_bio(ssl, sbio, sbio); //SSL_set_connect_state(ssl); @@ -442,16 +442,16 @@ int XrdHttpProtocol::Process(XrdLink *lp) // We ignore the argument here res = SSL_get_verify_result(ssl); TRACEI(DEBUG, " SSL_get_verify_result returned :" << res); ERR_print_errors(sslbio_err); - - + + // Get the voms string and auth information if (GetVOMSData(Link)) { SSL_free(ssl); ssl = 0; return -1; } - - + + if (res != X509_V_OK) return -1; ssldone = true; } @@ -484,7 +484,7 @@ int XrdHttpProtocol::Process(XrdLink *lp) // We ignore the argument here if (!CurrentReq.headerok) { - + // Read as many lines as possible into the buffer. An empty line breaks while ((rc = BuffgetLine(tmpline)) > 0) { TRACE(DEBUG, " rc:" << rc << " got hdr line: " << tmpline); @@ -634,7 +634,7 @@ int XrdHttpProtocol::Process(XrdLink *lp) // We ignore the argument here Bridge = XrdXrootd::Bridge::Login(&CurrentReq, Link, &SecEntity, SecEntity.name, "XrdHttp"); else Bridge = XrdXrootd::Bridge::Login(&CurrentReq, Link, &SecEntity, "unknown", "XrdHttp"); - + if (!Bridge) { TRACEI(REQ, " Autorization failed."); return -1; @@ -849,7 +849,7 @@ int XrdHttpProtocol::BuffgetLine(XrdOucString &dest) { *(p+1) = '\0'; // Remember the 1st segment int l1 = myBuff->buff + myBuff->bsize - myBuffStart; - + dest.assign(myBuffStart, 0, l1-1); //strncpy(dest, myBuffStart, l1); BuffConsume(l1); @@ -1302,8 +1302,11 @@ int XrdHttpProtocol::InitSecurity() { OpenSSL_add_all_digests(); const SSL_METHOD *meth; - -#ifdef HAVE_TLS12 + +#ifdef HAVE_TLS + meth = TLS_method(); + eDest.Say(" Using TLS"); +#elif defined (HAVE_TLS12) meth = TLSv1_2_method(); eDest.Say(" Using TLS 1.2"); #elif defined (HAVE_TLS11) @@ -1316,7 +1319,7 @@ int XrdHttpProtocol::InitSecurity() { eDest.Say(" warning: TLS is not available, falling back to SSL23 (deprecated)."); meth = SSLv23_method(); #endif - + sslctx = SSL_CTX_new((SSL_METHOD *)meth); //SSL_CTX_set_min_proto_version(sslctx, TLS1_2_VERSION); SSL_CTX_set_session_cache_mode(sslctx, SSL_SESS_CACHE_SERVER); @@ -1353,36 +1356,35 @@ int XrdHttpProtocol::InitSecurity() { exit(1); } } - - - SSL_CTX_set_cipher_list(sslctx, "ALL:!LOW:!EXP:!MD5:!MD2"); + + + SSL_CTX_set_cipher_list(sslctx, "ALL:!LOW:!EXP:!MD5:!MD2"); //SSL_CTX_set_purpose(sslctx, X509_PURPOSE_ANY); SSL_CTX_set_mode(sslctx, SSL_MODE_AUTO_RETRY); - + //eDest.Say(" Setting verify depth to ", itoa(sslverifydepth), "'."); SSL_CTX_set_verify_depth(sslctx, sslverifydepth); ERR_print_errors(sslbio_err); - SSL_CTX_set_verify(sslctx, - SSL_VERIFY_PEER, verify_callback); - + SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER, verify_callback); + // // Check existence of GRID map file if (gridmap) { - + // Initialize the GMap service // XrdOucString pars; if (XrdHttpTrace->What == TRACE_DEBUG) pars += "dbg|"; - + if (!(servGMap = XrdOucgetGMap(&eDest, gridmap, pars.c_str()))) { - eDest.Say("Error loading grid map file:", gridmap); - exit(1); + eDest.Say("Error loading grid map file:", gridmap); + exit(1); } else { - TRACE(ALL, "using grid map file: "<< gridmap); - } - + TRACE(ALL, "using grid map file: "<< gridmap); + } + } - + if (secxtractor) secxtractor->InitCTX(sslctx, XrdHttpTrace->What); ERR_print_errors(sslbio_err); @@ -1400,21 +1402,21 @@ void XrdHttpProtocol::Cleanup() { } if (ssl) { - - + + if (SSL_shutdown(ssl) != 1) { TRACE(ALL, " SSL_shutdown failed"); ERR_print_errors(sslbio_err); } - + if (secxtractor) secxtractor->FreeSSL(ssl); - + SSL_free(ssl); } - + ssl = 0; sbio = 0; @@ -1589,9 +1591,9 @@ int XrdHttpProtocol::xsslkey(XrdOucStream & Config) { Purpose: To parse the directive: gridmap the path of the gridmap file to be used. Normally - it's /etc/grid-security/gridmap - No mapfile means no translation required - Pointing to a non existing mapfile is an error + it's /etc/grid-security/gridmap + No mapfile means no translation required + Pointing to a non existing mapfile is an error Output: 0 upon success or !0 upon failure. */ @@ -1691,7 +1693,7 @@ int XrdHttpProtocol::xsecretkey(XrdOucStream & Config) { } FILE *fp = fopen(val,"r"); - + if( fp == NULL ) { eDest.Emsg("Config", "Cannot open shared secret key file '", val, "'"); eDest.Emsg("Config", "Cannot open shared secret key file. err: ", strerror(errno)); diff --git a/src/XrdHttp/XrdHttpUtils.cc b/src/XrdHttp/XrdHttpUtils.cc index 02a817b0186..3c1b233471f 100644 --- a/src/XrdHttp/XrdHttpUtils.cc +++ b/src/XrdHttp/XrdHttpUtils.cc @@ -56,6 +56,20 @@ #include "XrdOuc/XrdOucString.hh" static pthread_key_t cm_key; +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static HMAC_CTX* HMAC_CTX_new() { + HMAC_CTX *ctx = (HMAC_CTX *)OPENSSL_malloc(sizeof(HMAC_CTX)); + if (ctx) HMAC_CTX_init(ctx); + return ctx; +} + +static void HMAC_CTX_free(HMAC_CTX *ctx) { + if (ctx) { + HMAC_CTX_cleanup(ctx); + OPENSSL_free(ctx); + } +} +#endif // GetHost from URL @@ -65,7 +79,7 @@ int parseURL(char *url, char *host, int &port, char **path) { // http://x.y.z.w:p/path *path = 0; - + // look for the second slash char *p = strstr(url, "//"); if (!p) return -1; @@ -76,7 +90,7 @@ int parseURL(char *url, char *host, int &port, char **path) { // look for the end of the host:port char *p2 = strchr(p, '/'); if (!p2) return -1; - + *path = p2; char buf[256]; @@ -166,7 +180,7 @@ char *mystrchrnul(const char *s, int c) { // - hash is a string that will be filled with the hash // // - fn: the original filename that was requested -// - dhost: target redirection hostname +// - dhost: target redirection hostname // - client: address:port of the client // - tim: creation time of the url // - tim_grace: validity time before and after creation time @@ -190,7 +204,7 @@ void calcHashes( const char *key) { - HMAC_CTX ctx; + HMAC_CTX *ctx; unsigned int len; unsigned char mdbuf[EVP_MAX_MD_SIZE]; char buf[64]; @@ -214,43 +228,46 @@ void calcHashes( return; } - HMAC_CTX_init(&ctx); + ctx = HMAC_CTX_new(); + if (!ctx) { + return; + } - HMAC_Init_ex(&ctx, (const void *) key, strlen(key), EVP_sha256(), 0); + HMAC_Init_ex(ctx, (const void *) key, strlen(key), EVP_sha256(), 0); if (fn) - HMAC_Update(&ctx, (const unsigned char *) fn, + HMAC_Update(ctx, (const unsigned char *) fn, strlen(fn) + 1); - HMAC_Update(&ctx, (const unsigned char *) &request, + HMAC_Update(ctx, (const unsigned char *) &request, sizeof (request)); if (secent->name) - HMAC_Update(&ctx, (const unsigned char *) secent->name, + HMAC_Update(ctx, (const unsigned char *) secent->name, strlen(secent->name) + 1); if (secent->vorg) - HMAC_Update(&ctx, (const unsigned char *) secent->vorg, + HMAC_Update(ctx, (const unsigned char *) secent->vorg, strlen(secent->vorg) + 1); if (secent->host) - HMAC_Update(&ctx, (const unsigned char *) secent->host, + HMAC_Update(ctx, (const unsigned char *) secent->host, strlen(secent->host) + 1); localtime_r(&tim, &tms); strftime(buf, sizeof (buf), "%s", &tms); - HMAC_Update(&ctx, (const unsigned char *) buf, + HMAC_Update(ctx, (const unsigned char *) buf, strlen(buf) + 1); - HMAC_Final(&ctx, mdbuf, &len); + HMAC_Final(ctx, mdbuf, &len); Tobase64(mdbuf, len / 2, hash); - HMAC_CTX_cleanup(&ctx); + HMAC_CTX_free(ctx); } int compareHash( diff --git a/src/XrdSecgsi/XrdSecgsiProxy.cc b/src/XrdSecgsi/XrdSecgsiProxy.cc index bfb5d34444f..96cf9b39fc0 100644 --- a/src/XrdSecgsi/XrdSecgsiProxy.cc +++ b/src/XrdSecgsi/XrdSecgsiProxy.cc @@ -89,7 +89,7 @@ bool CheckOption(XrdOucString opt, const char *ref, int &ival); void Display(XrdCryptoX509 *xp); // -// Globals +// Globals // int Mode = kM_undef; bool Debug = 0; @@ -307,7 +307,7 @@ int ParseArguments(int argc, char **argv) if(*(argv)[0] == '-') { opt = *argv; - opt.erase(0,1); + opt.erase(0,1); if (CheckOption(opt,"h",ival) || CheckOption(opt,"help",ival) || CheckOption(opt,"menu",ival)) { Mode = kM_help; @@ -679,12 +679,12 @@ bool CheckOption(XrdOucString opt, const char *ref, int &ival) // Check opt against ref // Return 1 if ok, 0 if not // Fills ival = 1 if match is exact - // ival = 0 if match is exact with no + // ival = 0 if match is exact with no // ival = -1 in the other cases bool rc = 0; int lref = (ref) ? strlen(ref) : 0; - if (!lref) + if (!lref) return rc; XrdOucString noref = ref; noref.insert("no",0); @@ -726,16 +726,19 @@ void Display(XrdCryptoX509 *xp) PRT("subject : "<Subject()); // Path length field int pathlen = 0; bool b; - (*ProxyCertInfo)(xp->GetExtension(gsiProxyCertInfo_OID), pathlen, &b); + if(xp->GetExtension(gsiProxyCertInfo_OID)) + (*ProxyCertInfo)(xp->GetExtension(gsiProxyCertInfo_OID), pathlen, &b); + else + (*ProxyCertInfo)(xp->GetExtension(gsiProxyCertInfo_OLD_OID), pathlen, &b); PRT("path length : "<BitStrength()); // Time left int now = int(time(0)) - XrdCryptoTZCorr(); int tl = xp->NotAfter() - now; - int hh = (tl >= 3600) ? (tl/3600) : 0; tl -= (hh*3600); - int mm = (tl >= 60) ? (tl/60) : 0; tl -= (mm*60); - int ss = (tl >= 0) ? tl : 0; + int hh = (tl >= 3600) ? (tl/3600) : 0; tl -= (hh*3600); + int mm = (tl >= 60) ? (tl/60) : 0; tl -= (mm*60); + int ss = (tl >= 0) ? tl : 0; PRT("time left : "<