//
using System;
+using System.Globalization;
using System.Security.Cryptography;
using System.Text;
#else
public
#endif
- class CryptoConvert {
+ sealed class CryptoConvert {
+
+ private CryptoConvert ()
+ {
+ }
static private int ToInt32LE (byte [] bytes, int offset)
{
for (int i=0; i < array.Length; i++) {
if (array [i] != 0x00) {
byte[] result = new byte [array.Length - i];
- Array.Copy (array, i, result, 0, result.Length);
+ Buffer.BlockCopy (array, i, result, 0, result.Length);
return result;
}
}
throw new CryptographicException ("Invalid blob header");
// ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...)
- int algId = ToInt32LE (blob, offset+4);
+ // int algId = ToInt32LE (blob, offset+4);
// DWORD bitlen
int bitLen = ToInt32LE (blob, offset+12);
// DWORD public exponent
RSAParameters rsap = new RSAParameters ();
byte[] exp = new byte [4];
- Array.Copy (blob, offset+16, exp, 0, 4);
+ Buffer.BlockCopy (blob, offset+16, exp, 0, 4);
Array.Reverse (exp);
rsap.Exponent = Trim (exp);
// BYTE modulus[rsapubkey.bitlen/8];
int byteLen = (bitLen >> 3);
rsap.Modulus = new byte [byteLen];
- Array.Copy (blob, pos, rsap.Modulus, 0, byteLen);
+ Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen);
Array.Reverse (rsap.Modulus);
pos += byteLen;
// BYTE prime1[rsapubkey.bitlen/16];
int byteHalfLen = (byteLen >> 1);
rsap.P = new byte [byteHalfLen];
- Array.Copy (blob, pos, rsap.P, 0, byteHalfLen);
+ Buffer.BlockCopy (blob, pos, rsap.P, 0, byteHalfLen);
Array.Reverse (rsap.P);
pos += byteHalfLen;
// BYTE prime2[rsapubkey.bitlen/16];
rsap.Q = new byte [byteHalfLen];
- Array.Copy (blob, pos, rsap.Q, 0, byteHalfLen);
+ Buffer.BlockCopy (blob, pos, rsap.Q, 0, byteHalfLen);
Array.Reverse (rsap.Q);
pos += byteHalfLen;
// BYTE exponent1[rsapubkey.bitlen/16];
rsap.DP = new byte [byteHalfLen];
- Array.Copy (blob, pos, rsap.DP, 0, byteHalfLen);
+ Buffer.BlockCopy (blob, pos, rsap.DP, 0, byteHalfLen);
Array.Reverse (rsap.DP);
pos += byteHalfLen;
// BYTE exponent2[rsapubkey.bitlen/16];
rsap.DQ = new byte [byteHalfLen];
- Array.Copy (blob, pos, rsap.DQ, 0, byteHalfLen);
+ Buffer.BlockCopy (blob, pos, rsap.DQ, 0, byteHalfLen);
Array.Reverse (rsap.DQ);
pos += byteHalfLen;
// BYTE coefficient[rsapubkey.bitlen/16];
rsap.InverseQ = new byte [byteHalfLen];
- Array.Copy (blob, pos, rsap.InverseQ, 0, byteHalfLen);
+ Buffer.BlockCopy (blob, pos, rsap.InverseQ, 0, byteHalfLen);
Array.Reverse (rsap.InverseQ);
pos += byteHalfLen;
- // BYTE privateExponent[rsapubkey.bitlen/8];
- rsap.D = new byte [byteLen];
- Array.Copy (blob, pos, rsap.D, 0, byteLen);
- Array.Reverse (rsap.D);
+ // ok, this is hackish but CryptoAPI support it so...
+ // note: only works because CRT is used by default
+ // http://bugzilla.ximian.com/show_bug.cgi?id=57941
+ rsap.D = new byte [byteLen]; // must be allocated
+ if (pos + byteLen + offset <= blob.Length) {
+ // BYTE privateExponent[rsapubkey.bitlen/8];
+ Buffer.BlockCopy (blob, pos, rsap.D, 0, byteLen);
+ Array.Reverse (rsap.D);
+ }
RSA rsa = (RSA)RSA.Create ();
rsa.ImportParameters (rsap);
byte[] part = p.Modulus;
int len = part.Length;
Array.Reverse (part, 0, len);
- Array.Copy (part, 0, blob, pos, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
// private key
part = p.P;
len = part.Length;
Array.Reverse (part, 0, len);
- Array.Copy (part, 0, blob, pos, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
part = p.Q;
len = part.Length;
Array.Reverse (part, 0, len);
- Array.Copy (part, 0, blob, pos, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
part = p.DP;
len = part.Length;
Array.Reverse (part, 0, len);
- Array.Copy (part, 0, blob, pos, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
part = p.DQ;
len = part.Length;
Array.Reverse (part, 0, len);
- Array.Copy (part, 0, blob, pos, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
part = p.InverseQ;
len = part.Length;
Array.Reverse (part, 0, len);
- Array.Copy (part, 0, blob, pos, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
part = p.D;
len = part.Length;
Array.Reverse (part, 0, len);
- Array.Copy (part, 0, blob, pos, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
return blob;
}
throw new CryptographicException ("Invalid blob header");
// ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...)
- int algId = ToInt32LE (blob, offset+4);
+ // int algId = ToInt32LE (blob, offset+4);
// DWORD bitlen
int bitLen = ToInt32LE (blob, offset+12);
// BYTE modulus[rsapubkey.bitlen/8];
int byteLen = (bitLen >> 3);
rsap.Modulus = new byte [byteLen];
- Array.Copy (blob, pos, rsap.Modulus, 0, byteLen);
+ Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen);
Array.Reverse (rsap.Modulus);
RSA rsa = (RSA)RSA.Create ();
byte[] part = p.Modulus;
int len = part.Length;
Array.Reverse (part, 0, len);
- Array.Copy (part, 0, blob, pos, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
return blob;
}
if (rsa == null)
throw new ArgumentNullException ("rsa");
- RSAParameters p = rsa.ExportParameters (includePrivateKey);
+ rsa.ExportParameters (includePrivateKey);
if (includePrivateKey)
return ToCapiPrivateKeyBlob (rsa);
else
StringBuilder sb = new StringBuilder (input.Length * 2);
foreach (byte b in input) {
- sb.Append (b.ToString ("X2"));
+ sb.Append (b.ToString ("X2", CultureInfo.InvariantCulture));
}
return sb.ToString ();
}