// Jesper Pedersen <jep@itplus.dk>
//
// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
-// (C) 2004 Novell (http://www.novell.com)
// (C) 2004 IT+ A/S (http://www.itplus.dk)
-//
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
#else
public
#endif
- sealed class ASN1Convert {
-
- private ASN1Convert ()
- {
- }
-
+ static class ASN1Convert {
// RFC3280, section 4.2.1.5
// CAs conforming to this profile MUST always encode certificate
// validity dates through the year 2049 as UTCTime; certificate validity
// dates in 2050 or later MUST be encoded as GeneralizedTime.
+
+ // Under 1.x this API requires a Local datetime to be provided
+ // Under 2.0 it will also accept a Utc datetime
static public ASN1 FromDateTime (DateTime dt)
{
if (dt.Year < 2050) {
asn1.Value = integer;
break;
case 4:
- asn1.Value = new byte [0];
+ asn1.Value = new byte [1];
break;
default:
byte[] smallerInt = new byte [4 - x];
{
if (big == null)
throw new ArgumentNullException ("big");
-
- if (big [0] != 0x00) {
- // this first byte is added so we're sure this is an unsigned integer
- // however we can't feed it into RSAParameters or DSAParameters
+
+ // check for numbers that could be interpreted as negative (first bit)
+ if (big [0] >= 0x80) {
+ // in thie cas we add a new, empty, byte (position 0) so we're
+ // sure this will always be interpreted an unsigned integer.
+ // However we can't feed it into RSAParameters or DSAParameters
int length = big.Length + 1;
byte[] uinteger = new byte [length];
Buffer.BlockCopy (big, 0, uinteger, 1, length - 1);
string t = Encoding.ASCII.GetString (time.Value);
// to support both UTCTime and GeneralizedTime (and not so common format)
string mask = null;
+ int year;
switch (t.Length) {
case 11:
- mask = "yyMMddHHmmZ"; // illegal I think ... must check
+ // illegal format, still it's supported for compatibility
+ mask = "yyMMddHHmmZ";
break;
case 13:
// RFC3280: 4.1.2.5.1 UTCTime
- int year = Convert.ToInt16 (t.Substring (0, 2), CultureInfo.InvariantCulture);
+ year = Convert.ToInt16 (t.Substring (0, 2), CultureInfo.InvariantCulture);
// Where YY is greater than or equal to 50, the
// year SHALL be interpreted as 19YY; and
// Where YY is less than 50, the year SHALL be
case 15:
mask = "yyyyMMddHHmmssZ"; // GeneralizedTime
break;
+ case 17:
+ // another illegal format (990630000000+1000), again supported for compatibility
+ year = Convert.ToInt16 (t.Substring (0, 2), CultureInfo.InvariantCulture);
+ string century = (year >= 50) ? "19" : "20";
+ // ASN.1 (see ITU X.680 section 43.3) deals with offset differently than .NET
+ char sign = (t[12] == '+') ? '-' : '+';
+ t = String.Format ("{0}{1}{2}{3}{4}:{5}{6}", century, t.Substring (0, 12), sign,
+ t[13], t[14], t[15], t[16]);
+ mask = "yyyyMMddHHmmsszzz";
+ break;
}
- return DateTime.ParseExact (t, mask, null);
+ return DateTime.ParseExact (t, mask, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
}
}
}