diff --git a/src/XrdCrypto/XrdCryptoCipher.cc b/src/XrdCrypto/XrdCryptoCipher.cc index a09ef750bd4..52475f43f71 100644 --- a/src/XrdCrypto/XrdCryptoCipher.cc +++ b/src/XrdCrypto/XrdCryptoCipher.cc @@ -58,7 +58,7 @@ bool XrdCryptoCipher::IsValid() //____________________________________________________________________________ void XrdCryptoCipher::SetIV(int l, const char *iv) { - // Set IV from l bytes at iv + // Set IV from l bytes at iv. If !iv, sets the IV length. ABSTRACTMETHOD("XrdCryptoCipher::SetIV"); } diff --git a/src/XrdCrypto/XrdCryptosslCipher.cc b/src/XrdCrypto/XrdCryptosslCipher.cc index 406a5554ce8..8c790360654 100644 --- a/src/XrdCrypto/XrdCryptosslCipher.cc +++ b/src/XrdCrypto/XrdCryptosslCipher.cc @@ -963,7 +963,7 @@ XrdSutBucket *XrdCryptosslCipher::AsBucket() //____________________________________________________________________________ void XrdCryptosslCipher::SetIV(int l, const char *iv) { - // Set IV from l bytes at iv + // Set IV from l bytes at iv. If !iv, sets the IV length. if (fIV) { delete[] fIV; @@ -971,12 +971,12 @@ void XrdCryptosslCipher::SetIV(int l, const char *iv) lIV = 0; } - if (iv && l > 0) { - fIV = new char[l]; - if (fIV) { - memcpy(fIV,iv,l); - lIV = l; + if (l > 0) { + if (iv) { + fIV = new char[l]; + if (fIV) memcpy(fIV,iv,l); } + lIV = l; } } @@ -1127,5 +1127,5 @@ int XrdCryptosslCipher::MaxIVLength() const { // Return the max cipher IV length - return EVP_MAX_IV_LENGTH; + return (lIV > 0) ? lIV : EVP_MAX_IV_LENGTH; } diff --git a/src/XrdSecgsi/XrdSecProtocolgsi.cc b/src/XrdSecgsi/XrdSecProtocolgsi.cc index 4d0c6c1ddfc..2879a1ff167 100644 --- a/src/XrdSecgsi/XrdSecProtocolgsi.cc +++ b/src/XrdSecgsi/XrdSecProtocolgsi.cc @@ -3150,7 +3150,7 @@ int XrdSecProtocolgsi::ClientDoCert(XrdSutBuffer *br, XrdSutBuffer **bm, // Parse the list int from = 0; while ((from = ciplist.tokenize(cip, from, ':')) != -1) { - if (cip.length() > 0) + if (cip.length() > 0) if (sessionCF->SupportedCipher(cip.c_str())) break; cip = ""; @@ -3161,8 +3161,6 @@ int XrdSecProtocolgsi::ClientDoCert(XrdSutBuffer *br, XrdSutBuffer **bm, hs->Chain = 0; return -1; } - // Communicate to server - br->UpdateBucket(cip, kXRS_cipher_alg); } else { NOTIFY("WARNING: list of ciphers supported by server missing" " - using default"); @@ -3313,6 +3311,17 @@ int XrdSecProtocolgsi::ClientDoCert(XrdSutBuffer *br, XrdSutBuffer **bm, return -1; } + // + // Communicate the cipher name to server + if (hs->RemVers >= XrdSecgsiVersDHsigned) { + // Including the length of the IV if supported + String cipiv; + String::form(cipiv, "%s#%d", cip.c_str(), sessionKey->MaxIVLength()); + br->UpdateBucket(cipiv, kXRS_cipher_alg); + } else { + br->UpdateBucket(cip, kXRS_cipher_alg); + } + // Deactivate what not needed any longer if (hs->RemVers >= XrdSecgsiVersDHsigned) { br->Deactivate(kXRS_cipher); @@ -3641,9 +3650,17 @@ int XrdSecProtocolgsi::ServerDoCert(XrdSutBuffer *br, XrdSutBuffer **bm, } // // Extract cipher algorithm chosen by the client + int lenIV = 0; String cip = ""; if ((bck = br->GetBucket(kXRS_cipher_alg))) { bck->ToString(cip); + // Extract IV length, if any + int piv = cip.find('#'); + if (piv >= 0) { + String siv(cip, piv+1); + if (siv.isdigit()) lenIV = siv.atoi(); + cip.erase(piv); + } // Parse the list if (DefCipher.find(cip) == -1) { cmsg = "unsupported cipher chosen by the client"; @@ -3723,6 +3740,10 @@ int XrdSecProtocolgsi::ServerDoCert(XrdSutBuffer *br, XrdSutBuffer **bm, hs->Chain = 0; return -1; } + + // Set IV length, if any + if (lenIV > 0) sessionKey->SetIV(lenIV, (const char *)0); + } else { cmsg = "bucket with DH parameters not found or invalid: cannot finalize session cipher"; return -1; diff --git a/src/XrdSut/XrdSutBuffer.cc b/src/XrdSut/XrdSutBuffer.cc index 90041eeb127..5a8f63daf59 100644 --- a/src/XrdSut/XrdSutBuffer.cc +++ b/src/XrdSut/XrdSutBuffer.cc @@ -237,9 +237,10 @@ int XrdSutBuffer::UpdateBucket(XrdOucString s, int ty) } //_____________________________________________________________________________ -void XrdSutBuffer::Dump(const char *stepstr) +void XrdSutBuffer::Dump(const char *stepstr, bool all) { - // Dump content of buffer + // Dump content of buffer. If all is false, only active buckets are dumped; + // this is the default behaviour. EPNAME("Buffer::Dump"); PRINT("//-----------------------------------------------------//"); @@ -262,18 +263,25 @@ void XrdSutBuffer::Dump(const char *stepstr) } else { PRINT("// Step : " <Dump(0); + if (all || bp->type != kXRS_inactive) { + PRINT("// buck: " <Dump(0); + } // Get next bp = fBuckets.Next(); } + if (!all) PRINT("// # active buckets found: " << kb); PRINT("// //") PRINT("//-----------------------------------------------------//"); } diff --git a/src/XrdSut/XrdSutBuffer.hh b/src/XrdSut/XrdSutBuffer.hh index 9fb36842f95..615a3471f16 100644 --- a/src/XrdSut/XrdSutBuffer.hh +++ b/src/XrdSut/XrdSutBuffer.hh @@ -71,7 +71,7 @@ public: // Remove from the list, to avoid destroy by ~XrdSutBuffer void Remove(XrdSutBucket *b) { fBuckets.Remove(b); } - void Dump(const char *stepstr = 0); + void Dump(const char *stepstr = 0, bool all = false); void Message(const char *prepose = 0); int Serialized(char **buffer, char opt = 'n');