internal RSAParameters ParseRSAPrivateKey()
{
var parameters = new RSAParameters ();
// Current value
byte[] value = null;
// Checkpoint
int position = parser.CurrentPosition ();
// Sanity Check
int length = 0;
// Ignore Sequence - PrivateKeyInfo
length = parser.NextSequence ();
if (length != parser.RemainingBytes ())
{
var sb = new StringBuilder("Incorrect Sequence Size. ");
sb.AppendFormat("Specified: {0}, Remaining: {1}",
length.ToString(CultureInfo.InvariantCulture),
parser.RemainingBytes ().ToString(CultureInfo.InvariantCulture));
throw new BerDecodeException(sb.ToString (), position);
}
// Checkpoint
position = parser.CurrentPosition ();
// Version
value = parser.NextInteger ();
if (0x00 != value[0])
{
var sb = new StringBuilder("Incorrect PrivateKeyInfo Version. ");
var v = new BigInteger(value);
sb.AppendFormat("Expected: 0, Specified: {0}", v.ToString ());
throw new BerDecodeException(sb.ToString (), position);
}
// Checkpoint
position = parser.CurrentPosition ();
// Ignore Sequence - AlgorithmIdentifier
length = parser.NextSequence ();
if (length > parser.RemainingBytes ())
{
var sb = new StringBuilder("Incorrect AlgorithmIdentifier Size. ");
sb.AppendFormat("Specified: {0}, Remaining: {1}",
length.ToString(CultureInfo.InvariantCulture),
parser.RemainingBytes ().ToString(CultureInfo.InvariantCulture));
throw new BerDecodeException(sb.ToString (), position);
}
// Checkpoint
position = parser.CurrentPosition ();
// Grab the OID
value = parser.NextOID ();
byte[] oid = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01};
if (!EqualOid(value, oid))
{
throw new BerDecodeException("Expected OID 1.2.840.113549.1.1.1", position);
}
// Optional Parameters
if (parser.IsNextNull ())
{
parser.NextNull ();
// Also OK: value = parser.Next();
}
else
{
// Gracefully skip the optional data
value = parser.Next ();
}
// Checkpoint
position = parser.CurrentPosition ();
// Ignore OctetString - PrivateKey
length = parser.NextOctetString ();
if (length > parser.RemainingBytes ())
{
var sb = new StringBuilder("Incorrect PrivateKey Size. ");
sb.AppendFormat("Specified: {0}, Remaining: {1}",
length.ToString(CultureInfo.InvariantCulture),
parser.RemainingBytes ().ToString(CultureInfo.InvariantCulture));
throw new BerDecodeException(sb.ToString (), position);
}
// Checkpoint
position = parser.CurrentPosition ();
// Ignore Sequence - RSAPrivateKey
length = parser.NextSequence ();
if (length < parser.RemainingBytes ())
{
var sb = new StringBuilder("Incorrect RSAPrivateKey Size. ");
sb.AppendFormat("Specified: {0}, Remaining: {1}",
length.ToString(CultureInfo.InvariantCulture),
parser.RemainingBytes ().ToString(CultureInfo.InvariantCulture));
throw new BerDecodeException(sb.ToString (), position);
}
// Checkpoint
position = parser.CurrentPosition ();
// Version
value = parser.NextInteger ();
if (0x00 != value[0])
{
var sb = new StringBuilder("Incorrect RSAPrivateKey Version. ");
var v = new BigInteger(value);
sb.AppendFormat("Expected: 0, Specified: {0}", v.ToString ());
throw new BerDecodeException(sb.ToString (), position);
}
parameters.Modulus = TrimLeadingZero(parser.NextInteger ());
parameters.Exponent = TrimLeadingZero(parser.NextInteger ());
parameters.D = TrimLeadingZero(parser.NextInteger ());
parameters.P = TrimLeadingZero(parser.NextInteger ());
parameters.Q = TrimLeadingZero(parser.NextInteger ());
parameters.DP = TrimLeadingZero(parser.NextInteger ());
parameters.DQ = TrimLeadingZero(parser.NextInteger ());
parameters.InverseQ = TrimLeadingZero(parser.NextInteger ());
Debug.Assert(0 == parser.RemainingBytes ());
return parameters;
}