Index: Mono.Security.Cryptography/ChangeLog
===================================================================
--- Mono.Security.Cryptography/ChangeLog (revision 65893)
+++ Mono.Security.Cryptography/ChangeLog (working copy)
@@ -1,3 +1,10 @@
+2006-09-27 Sebastien Pouliot <sebastien@ximian.com>
+
+ * RSAManaged.cs: Ensure that the results of Encrypt and Decrypt will
+ always be the same length as the key. If smaller then we left pad the
+ result with 0x00 (same integer, correct length for everyone). Fix bug
+ #79502 where an LDAP/SSL server didn't like the missing byte.
+
2006-09-05 Sebastien Pouliot <sebastien@ximian.com>
* RSAManaged.cs: Backport NRE fix from mscorlib.dll.
Index: Mono.Security.Cryptography/RSAManaged.cs
===================================================================
--- Mono.Security.Cryptography/RSAManaged.cs (revision 65893)
+++ Mono.Security.Cryptography/RSAManaged.cs (working copy)
@@ -224,7 +224,9 @@
r.Clear ();
}
- byte[] result = output.GetBytes ();
+ // it's sometimes possible for the results to be a byte short
+ // and this can break some software (see #79502) so we 0x00 pad the result
+ byte[] result = GetPaddedValue (output);
// zeroize values
input.Clear ();
output.Clear ();
@@ -241,7 +243,9 @@
BigInteger input = new BigInteger (rgb);
BigInteger output = input.ModPow (e, n);
- byte[] result = output.GetBytes ();
+ // it's sometimes possible for the results to be a byte short
+ // and this can break some software (see #79502) so we 0x00 pad the result
+ byte[] result = GetPaddedValue (output);
// zeroize value
input.Clear ();
output.Clear ();
@@ -457,5 +461,20 @@
// possible (in case the key was imported)
get { return (!keypairGenerated || isCRTpossible); }
}
+
+ private byte[] GetPaddedValue (BigInteger value)
+ {
+ byte[] result = value.GetBytes ();
+ int length = (KeySize >> 8);
+ if (result.Length >= length)
+ return result;
+
+ // left-pad 0x00 value on the result (same integer, correct length)
+ byte[] padded = new byte[length];
+ Buffer.BlockCopy (result, 0, padded, (length - result.Length), result.Length);
+ // temporary result may contain decrypted (plaintext) data, clear it
+ Array.Clear (result, 0, result.Length);
+ return padded;
+ }
}
}