Blob Blame History Raw
diff --git a/cmake/FindOpenSSL.cmake b/cmake/FindOpenSSL.cmake
index 6b2a878..e7cfc76 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 e193555..9a44e4e 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 cf2f8ec..322ccd2 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 4d7b7aa..23635ab 100644
--- a/src/XrdCrypto/XrdCryptogsiX509Chain.cc
+++ b/src/XrdCrypto/XrdCryptogsiX509Chain.cc
@@ -170,6 +170,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: ";
@@ -238,7 +239,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 f7b809c..23e648b 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 '"<<cert->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 b8b4558..3cfc531 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 e15462b..4204df1 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: "<<in); 
-      if (lin <= 0) DEBUG("lin: "<<lin); 
-      if (!out) DEBUG("out: "<<out); 
+      DEBUG("wrong inputs arguments");
+      if (!in) DEBUG("in: "<<in);
+      if (lin <= 0) DEBUG("lin: "<<lin);
+      if (!out) DEBUG("out: "<<out);
       return 0;
    }
 
@@ -918,35 +1036,35 @@ int XrdCryptosslCipher::EncDec(int enc, const char *in, int lin, char *out)
    // Action depend on the length of the key wrt default length
    if (deflength) {
       // Init ctx, set key (default length) and set IV
-      if (!EVP_CipherInit_ex(&ctx, cipher, 0, (unsigned char *)Buffer(), iv, enc)) {
-         DEBUG("error initializing"); 
+      if (!EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)Buffer(), iv, enc)) {
+         DEBUG("error initializing");
          return 0;
       }
    } else {
       // Init ctx
-      if (!EVP_CipherInit_ex(&ctx, cipher, 0, 0, 0, enc)) {
-         DEBUG("error initializing - 1"); 
+      if (!EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, enc)) {
+         DEBUG("error initializing - 1");
          return 0;
       }
       // Set key length
-      EVP_CIPHER_CTX_set_key_length(&ctx,Length());
+      EVP_CIPHER_CTX_set_key_length(ctx,Length());
       // Set key and IV
-      if (!EVP_CipherInit_ex(&ctx, 0, 0, (unsigned char *)Buffer(), iv, enc)) {
-         DEBUG("error initializing - 2"); 
+      if (!EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)Buffer(), iv, enc)) {
+         DEBUG("error initializing - 2");
          return 0;
       }
    }
 
    // Encrypt / Decrypt
    int ltmp = 0;
-   if (!EVP_CipherUpdate(&ctx, (unsigned char *)&out[0], &ltmp,
+   if (!EVP_CipherUpdate(ctx, (unsigned char *)&out[0], &ltmp,
                                (unsigned char *)in, lin)) {
-      DEBUG("error encrypting"); 
+      DEBUG("error encrypting");
       return 0;
    }
    lout = ltmp;
-   if (!EVP_CipherFinal_ex(&ctx, (unsigned char *)&out[lout], &ltmp)) {
-      DEBUG("error finalizing"); 
+   if (!EVP_CipherFinal_ex(ctx, (unsigned char *)&out[lout], &ltmp)) {
+      DEBUG("error finalizing");
       return 0;
    }
 
@@ -960,7 +1078,7 @@ int XrdCryptosslCipher::EncOutLength(int l)
 {
    // Required buffer size for encrypting l bytes
 
-   return (l+EVP_CIPHER_CTX_block_size(&ctx));
+   return (l+EVP_CIPHER_CTX_block_size(ctx));
 }
 
 //____________________________________________________________________________
@@ -968,7 +1086,7 @@ int XrdCryptosslCipher::DecOutLength(int l)
 {
    // Required buffer size for decrypting l bytes
 
-   int lout = l+EVP_CIPHER_CTX_block_size(&ctx)+1;
+   int lout = l+EVP_CIPHER_CTX_block_size(ctx)+1;
    lout = (lout <= 0) ? l : lout;
    return lout;
 }
diff --git a/src/XrdCrypto/XrdCryptosslCipher.hh b/src/XrdCrypto/XrdCryptosslCipher.hh
index 0237579..e6e5c37 100644
--- a/src/XrdCrypto/XrdCryptosslCipher.hh
+++ b/src/XrdCrypto/XrdCryptosslCipher.hh
@@ -52,7 +52,7 @@ private:
    char       *fIV;
    int         lIV;
    const EVP_CIPHER *cipher;
-   EVP_CIPHER_CTX ctx;
+   EVP_CIPHER_CTX *ctx;
    DH         *fDH;
    bool        deflength;
    bool        valid;
diff --git a/src/XrdCrypto/XrdCryptosslFactory.cc b/src/XrdCrypto/XrdCryptosslFactory.cc
index 43ea86d..7fccedc 100644
--- a/src/XrdCrypto/XrdCryptosslFactory.cc
+++ b/src/XrdCrypto/XrdCryptosslFactory.cc
@@ -62,6 +62,7 @@ XrdSysMutex *XrdCryptosslFactory::CryptoMutexPool[SSLFACTORY_MAX_CRYPTO_MUTEX];
 /******************************************************************************/
 /*             T h r e a d - S a f e n e s s   F u n c t i o n s              */
 /******************************************************************************/
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 #ifdef __solaris__
 extern "C" {
 #endif
@@ -69,7 +70,7 @@ static unsigned long sslfactory_id_callback(void) {
   return (unsigned long)XrdSysThread::ID();
 }
 
-void sslfactory_lock(int mode, int n, const char *file, int line)
+static void sslfactory_lock(int mode, int n, const char *file, int line)
 {
   if (mode & CRYPTO_LOCK) {
     if (XrdCryptosslFactory::CryptoMutexPool[n]) {
@@ -84,6 +85,7 @@ void sslfactory_lock(int mode, int n, const char *file, int line)
 #ifdef __solaris__
 }
 #endif
+#endif
 
 
 //______________________________________________________________________________
diff --git a/src/XrdCrypto/XrdCryptosslRSA.cc b/src/XrdCrypto/XrdCryptosslRSA.cc
index 70e0622..65bf971 100644
--- a/src/XrdCrypto/XrdCryptosslRSA.cc
+++ b/src/XrdCrypto/XrdCryptosslRSA.cc
@@ -43,6 +43,27 @@
 #include <openssl/err.h>
 #include <openssl/pem.h>
 
+#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: "<<bits<<", exp:"<<exp);
+   DEBUG("bits: "<<bits<<", exp: "<<exp);
 
    // Try Key Generation
-   RSA *fRSA = RSA_generate_key(bits,exp,0,0);
+   RSA *fRSA = RSA_new();
+   if (!fRSA) {
+      DEBUG("cannot allocate new public key");
+      return;
+   }
+
+   BIGNUM *e = BN_new();
+   if (!e) {
+      DEBUG("cannot allocate new exponent");
+      RSA_free(fRSA);
+      return;
+   }
+
+   BN_set_word(e, exp);
 
    // Update status flag
-   if (fRSA) {
+   if (RSA_generate_key_ex(fRSA, bits, e, NULL) == 1) {
       if (RSA_check_key(fRSA) != 0) {
          status = kComplete;
          DEBUG("basic length: "<<RSA_size(fRSA)<<" bytes");
          // Set the key
-         EVP_PKEY_set1_RSA(fEVP, fRSA);
+         EVP_PKEY_assign_RSA(fEVP, fRSA);
       } else {
          DEBUG("WARNING: generated key is invalid");
          // Generated an invalid key: cleanup
          RSA_free(fRSA);
       }
+   } else {
+      RSA_free(fRSA);
    }
+
+   BN_free(e);
 }
 
 //_____________________________________________________________________________
@@ -123,7 +161,7 @@ XrdCryptosslRSA::XrdCryptosslRSA(EVP_PKEY *key, bool check)
 
    if (check) {
       // Check consistency
-      if (RSA_check_key(key->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: " <<serr);
@@ -506,7 +546,7 @@ int XrdCryptosslRSA::EncryptPublic(const char *in, int lin, char *out, int loutm
 
    //
    // Public encoding ...
-   int lcmax = RSA_size(fEVP->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: " <<serr);
@@ -557,7 +597,7 @@ int XrdCryptosslRSA::DecryptPrivate(const char *in, int lin, char *out, int lout
 
    int lout = 0;
    int len = lin;
-   int lcmax = RSA_size(fEVP->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: " <<serr);
@@ -606,7 +646,7 @@ int XrdCryptosslRSA::DecryptPublic(const char *in, int lin, char *out, int loutm
 
    int lout = 0;
    int len = lin;
-   int lcmax = RSA_size(fEVP->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: " <<serr);
diff --git a/src/XrdCrypto/XrdCryptosslX509.cc b/src/XrdCrypto/XrdCryptosslX509.cc
index 36b66aa..f256f1e 100644
--- a/src/XrdCrypto/XrdCryptosslX509.cc
+++ b/src/XrdCrypto/XrdCryptosslX509.cc
@@ -43,6 +43,16 @@
 
 #include <openssl/pem.h>
 
+#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 '"<<s<<"', critical: " << crit);
       // Dump its content
       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 = 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: "<<ret);
 
diff --git a/src/XrdCrypto/XrdCryptosslX509Crl.cc b/src/XrdCrypto/XrdCryptosslX509Crl.cc
index d253c98..609e14f 100644
--- a/src/XrdCrypto/XrdCryptosslX509Crl.cc
+++ b/src/XrdCrypto/XrdCryptosslX509Crl.cc
@@ -45,6 +45,13 @@
 #include <openssl/bn.h>
 #include <openssl/pem.h>
 
+#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: "<<tagser<<
@@ -403,7 +410,7 @@ int XrdCryptosslX509Crl::LoadCache()
             return -1;
          }
          // Add revocation date
-         cent->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 53b59b4..28621ab 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 22b600b..393fc79 100644
--- a/src/XrdCrypto/XrdCryptosslgsiAux.cc
+++ b/src/XrdCrypto/XrdCryptosslgsiAux.cc
@@ -36,7 +36,7 @@
 #include <sys/stat.h>
 
 #include <openssl/asn1.h>
-#include <openssl/asn1_mac.h>
+#include <openssl/asn1t.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
@@ -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: "<<fnc<<")"); 
+      PRINT("EEC certificate cannot be opened (file: "<<fnc<<")");
       return -kErrPX_BadEECfile;
    }
    fclose(fc);
    // Make sure the certificate is not expired
    int now = (int)time(0);
    if (now > 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: "<<sbj);
-      if ((ekEEC = PEM_read_PrivateKey(fk, &ekEEC, 0, 0))) {
+      if ((PEM_read_PrivateKey(fk, &ekEEC, 0, 0))) {
          DEBUG("EEC private key loaded from file: "<<fnk);
       } else {
          PRINT("unable to load EEC private key from file: "<<fnk);
          fclose(fk);
+         X509_free(xEEC);
          return -kErrPX_BadEECfile;
       }
    } else {
-      PRINT("EEC private key file cannot be opened (file: "<<fnk<<")"); 
+      PRINT("EEC private key file cannot be opened (file: "<<fnk<<")");
+      X509_free(xEEC);
       return -kErrPX_BadEECfile;
    }
    fclose(fk);
    // Check key consistency
-   if ((RSA_check_key(ekEEC->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 <rand_uint> 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: "<<serial<<", sn: "<<sn<<")"); 
+      PRINT("could not add CN - (serial: "<<serial<<", sn: "<<sn<<")");
       return -kErrPX_SetAttribute;
    }
    //
    // Set the name
    if (X509_REQ_set_subject_name(preq, psubj) != 1) {
-      PRINT("could not set subject name - return"); 
+      PRINT("could not set subject name - return");
       return -kErrPX_SetAttribute;
    }
    //
    // Create the extension CertProxyInfo
-   gsiProxyCertInfo_t *pci = gsiProxyCertInfo_new();
+   PROXY_CERT_INFO_EXTENSION *pci = PROXY_CERT_INFO_EXTENSION_new();
    if (!pci) {
-      PRINT("could not create structure for extension - return"); 
+      PRINT("could not create structure for extension - return");
       return -kErrPX_NoResources;
    }
+   pci->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 '"<<s<<"' in the stack"); 
+         PRINT("could not push the extension '"<<s<<"' in the stack");
          return -kErrPX_Error;
       }
       // Notify what we added
@@ -777,21 +535,21 @@ int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk,
 
    // Add the extension
    if (X509_add_ext(xPX, ext, -1) != 1) {
-      PRINT("could not add extension"); 
+      PRINT("could not add extension");
       return -kErrPX_SetAttribute;
    }
 
    //
    // Sign the certificate
-   if (!(X509_sign(xPX, ekEEC, EVP_md5()))) {
-      PRINT("problems signing the certificate"); 
+   if (!(X509_sign(xPX, ekEEC, EVP_sha1()))) {
+      PRINT("problems signing the certificate");
       return -kErrPX_Signing;
    }
 
    // Fill outputs
    XrdCryptoX509 *xcPX = new XrdCryptosslX509(xPX);
    if (!xcPX) {
-      PRINT("could not create container for proxy certificate"); 
+      PRINT("could not create container for proxy certificate");
       return -kErrPX_NoResources;
    }
    // We need the full key
@@ -799,16 +557,16 @@ int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk,
    xp->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: "<<fnp<<")"); 
+         PRINT("cannot open file to save the proxy certificate (file: "<<fnp<<")");
          fclose(fp);
          rc = -kErrPX_ProxyFile;
       }
       int ifp = fileno(fp);
       if (ifp == -1) {
          PRINT("got invalid file descriptor for the proxy certificate (file: "<<
-                fnp<<")"); 
+                fnp<<")");
          fclose(fp);
          rc = -kErrPX_ProxyFile;
       }
       // Set permissions to 0600
       if (fchmod(ifp, 0600) == -1) {
-         PRINT("cannot set permissions on file: "<<fnp<<" (errno: "<<errno<<")"); 
+         PRINT("cannot set permissions on file: "<<fnp<<" (errno: "<<errno<<")");
          fclose(fp);
          rc = -kErrPX_ProxyFile;
-      } 
+      }
 
       if (!rc && PEM_write_X509(fp, xPX) != 1) {
-         PRINT("error while writing proxy certificate"); 
+         PRINT("error while writing proxy certificate");
          fclose(fp);
          rc = -kErrPX_ProxyFile;
-      }   
+      }
       if (!rc && PEM_write_RSAPrivateKey(fp, kPX, 0, 0, 0, 0, 0) != 1) {
-         PRINT("error while writing proxy private key"); 
+         PRINT("error while writing proxy private key");
          fclose(fp);
          rc = -kErrPX_ProxyFile;
-      }   
+      }
       if (!rc && PEM_write_X509(fp, xEEC) != 1) {
-         PRINT("error while writing EEC certificate"); 
+         PRINT("error while writing EEC certificate");
          fclose(fp);
          rc = -kErrPX_ProxyFile;
-      }   
+      }
       fclose(fp);
       // Change
    }
@@ -877,7 +635,7 @@ int XrdCryptosslX509CreateProxyReq(XrdCryptoX509 *xcpi,
    // Return 0 in case of success, < 0 otherwise
    EPNAME("X509CreateProxyReq");
 
-   // Make sure we got an proxy certificate as input 
+   // Make sure we got an proxy certificate as input
    if (!xcpi || !(xcpi->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 <rand_uint> 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: "<<serial<<", sn: "<<sn<<")"); 
+      PRINT("could not add CN - (serial: "<<serial<<", sn: "<<sn<<")");
       return -kErrPX_SetAttribute;
    }
    //
    // Set the name
    if (X509_REQ_set_subject_name(xro, psubj) != 1) {
-      PRINT("could not set subject name - return"); 
+      PRINT("could not set subject name - return");
       return -kErrPX_SetAttribute;
    }
    //
    // Create the extension CertProxyInfo
-   gsiProxyCertInfo_t *pci = gsiProxyCertInfo_new();
+   PROXY_CERT_INFO_EXTENSION *pci = PROXY_CERT_INFO_EXTENSION_new();
    if (!pci) {
-      PRINT("could not create structure for extension - return"); 
+      PRINT("could not create structure for extension - return");
       return -kErrPX_NoResources;
    }
+   pci->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: "<<indepthlen);
       } else {
          // Duplicate and add to the stack
          X509_EXTENSION *xpiextdup = X509_EXTENSION_dup(xpiext);
          if (sk_X509_EXTENSION_push(esk, xpiextdup) == 0) {
-            PRINT("could not push the extension '"<<s<<"' in the stack"); 
+            PRINT("could not push the extension '"<<s<<"' in the stack");
             return -kErrPX_Error;
          }
          // Notify what we added
@@ -1021,11 +798,11 @@ int XrdCryptosslX509CreateProxyReq(XrdCryptoX509 *xcpi,
    //
    // Set the new length
    if (indepthlen > -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: "<<indepthlen);
       }
       // Flag key usage extension
       if (!haskeyusage && !strcmp(s, KEY_USAGE_OID)) haskeyusage = 1;
       // Fail if a subject alternative name extension is found
       if (!strcmp(s, SUBJ_ALT_NAME_OID)) {
-         PRINT("subject alternative name extension not allowed! Skipping request"); 
-         return -kErrPX_BadExtension;         
+         PRINT("subject alternative name extension not allowed! Skipping request");
+         return -kErrPX_BadExtension;
       }
       // Attach to ProxyCertInfo extension if any
-      if (!strcmp(s, gsiProxyCertInfo_OID)) {
+      if (!strcmp(s, gsiProxyCertInfo_OID) ||
+          !strcmp(s, gsiProxyCertInfo_OLD_OID)) {
          if (xriext) {
-            PRINT("more than one ProxyCertInfo extension! Skipping request"); 
+            PRINT("more than one ProxyCertInfo extension! Skipping request");
             return -kErrPX_BadExtension;
          }
          xriext = xpiext;
@@ -1267,7 +1040,7 @@ int XrdCryptosslX509SignProxyReq(XrdCryptoX509 *xcpi, XrdCryptoRSA *kcpi,
          // Duplicate and add to the stack
          X509_EXTENSION *xpiextdup = X509_EXTENSION_dup(xpiext);
          if (X509_add_ext(xpo, xpiextdup, -1) == 0) {
-            PRINT("could not push the extension '"<<s<<"' in the stack"); 
+            PRINT("could not push the extension '"<<s<<"' in the stack");
             return -kErrPX_Error;
          }
          // Notify what we added
@@ -1289,89 +1062,81 @@ int XrdCryptosslX509SignProxyReq(XrdCryptoX509 *xcpi, XrdCryptoRSA *kcpi,
    int nriext = sk_num(xrisk);
 #endif /* OPENSSL */
    if (nriext == 0 || !haskeyusage) {
-      PRINT("wrong extensions in request: "<< nriext<<", "<<haskeyusage); 
+      PRINT("wrong extensions in request: "<< nriext<<", "<<haskeyusage);
       return -kErrPX_BadExtension;
    }
    //
    // Get the content
    int reqdepthlen = -1;
-   unsigned char *p = xriext->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: "<<reqdepthlen);
-   
+
    // We allow max indepthlen-1
    int outdepthlen = (reqdepthlen < indepthlen) ? reqdepthlen :
-                                                 (indepthlen - 1); 
+                                                 (indepthlen - 1);
    //
    // Create the extension CertProxyInfo
-   gsiProxyCertInfo_t *pci = gsiProxyCertInfo_new();
+   PROXY_CERT_INFO_EXTENSION *pci = PROXY_CERT_INFO_EXTENSION_new();
    if (!pci) {
-      PRINT("could not create structure for extension - return"); 
+      PRINT("could not create structure for extension - return");
       return -kErrPX_NoResources;
    }
-
+   pci->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:"<<objstr<< " (getvat: "<<getvat<<")");
             } else {
                PRINT("ERROR:AOBJ: BAD OBJECT");
@@ -1532,7 +1297,7 @@ int XrdCryptosslX509FillVOMS(XRDGSI_CONST unsigned char **pp,
                }
             }
             if (os) {
-               M_ASN1_OCTET_STRING_free(os);
+               ASN1_OCTET_STRING_free(os);
                os = 0;
             }
          }
@@ -1552,7 +1317,7 @@ int XrdCryptosslX509FillVOMS(XRDGSI_CONST unsigned char **pp,
    }
 end:
    if (o) ASN1_OBJECT_free(o);
-   if (os) M_ASN1_OCTET_STRING_free(os);
+   if (os) ASN1_OCTET_STRING_free(os);
    *pp = p;
    DEBUG("ret: "<<ret<<" - getvat: "<<getvat);
 
@@ -1564,7 +1329,7 @@ int XrdCryptosslX509CheckProxy3(XrdCryptoX509 *xcpi, XrdOucString &emsg) {
    //
    // Check GSI 3 proxy info extension
    EPNAME("X509CheckProxy3");
-  
+
    // Point to the cerificate
    X509 *cert = (X509 *)(xcpi->Opaque());
 
@@ -1577,32 +1342,42 @@ int XrdCryptosslX509CheckProxy3(XrdCryptoX509 *xcpi, XrdOucString &emsg) {
    TRACE(ALL,"certificate has "<<numext<<" extensions");
 
    X509_EXTENSION *ext = 0;
+   PROXY_CERT_INFO_EXTENSION *pci = 0;
    for (int i = 0; i < numext; i++) {
       // Get the extension
       X509_EXTENSION *xext = X509_get_ext(cert, i);
-      // We are looking for gsiProxyCertInfo_OID ("1.3.6.1.4.1.3536.1.222")
+      // We are looking for gsiProxyCertInfo_OID     ("1.3.6.1.5.5.7.1.14")
+      //                 or gsiProxyCertInfo_OLD_OID ("1.3.6.1.4.1.3536.1.222")
       char s[256];
       OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(xext), 1);
       DEBUG(i << ": got: "<< s);
       if (!strncmp(s, gsiProxyCertInfo_OID, sizeof(gsiProxyCertInfo_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(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 bed781f..aac3943 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 e4caebf..5fe4d75 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 <path>
 
              <path>    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 02a817b..3c1b233 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 bfb5d34..96cf9b3 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<ref> 
+   //       ival = 0 if match is exact with no<ref>
    //       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     : "<<xp->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 : "<<pathlen);
    // Key strength
    PRT("bits        : "<<xp->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   : "<<hh<<"h:"<<mm<<"m:"<<ss<<"s");
    PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
    // Show VOMS attributes, if any