예제 #1
0
		static public ASN1 AlgorithmIdentifier (string oid)
		{
			ASN1 ai = new ASN1 (0x30);
			ai.Add (ASN1Convert.FromOid (oid));
			ai.Add (new ASN1 (0x05));	// NULL
			return ai;
		}
		[Test]
		public void ConvertDateTimeInvalidButExistingFormat () 
		{
			string nosecs = "9912312359Z"; 
			ASN1 dt = new ASN1 (0x18, Encoding.ASCII.GetBytes (nosecs));
			DateTime actual = ASN1Convert.ToDateTime (dt);
			AssertEquals ("DateTime", nosecs, actual.ToUniversalTime ().ToString ("yyMMddHHmm") + "Z");
예제 #3
0
		// Class(60) {
		//   OID(spnego),
		//   Class(A0) {
		//     Class(30) {
		//       Class(A0) {
		//         Class(30) { OID,OID,OID} },
		//       Class(A2) { OctetStream } } } }
		public byte [] ProcessSpnegoInitialContextTokenRequest ()
		{
			Type1Message type1 = new Type1Message (NtlmVersion.Version3);
			type1.Flags = unchecked ((NtlmFlags) 0xE21882B7);
			type1.Domain = "WORKGROUP"; // FIXME: remove it

			ASN1 asn = new ASN1 (0x60);
			ASN1 asn2 = new ASN1 (0xA0);
			ASN1 asn21 = new ASN1 (0x30);
			ASN1 asn211 = new ASN1 (0xA0);
			ASN1 asn2111 = new ASN1 (0x30);
			asn211.Add (asn2111);
			asn2111.Add (ASN1Convert.FromOid (Constants.OidNtlmSsp));
			asn2111.Add (ASN1Convert.FromOid (Constants.OidKerberos5));
			asn2111.Add (ASN1Convert.FromOid (Constants.OidMIT));
			ASN1 asn212 = new ASN1 (0xA2);
			ASN1 asn2121 = new ASN1 (0x4);
			asn2121.Value = type1.GetBytes ();
			asn212.Add (asn2121);
			asn21.Add (asn211);
			asn21.Add (asn212);
			asn2.Add (asn21);
			asn.Add (ASN1Convert.FromOid (Constants.OidSpnego));
			asn.Add (asn2);
			return asn.GetBytes ();
		}
예제 #4
0
        // Convert a binary encoded OID to human readable string representation of 
        // an OID (IETF style). Based on DUMPASN1.C from Peter Gutmann.
        static public string ToOid(ASN1 asn1)
        {
            if (asn1 == null)
                throw new ArgumentNullException("asn1");

            byte[] aOID = asn1.Value;
            StringBuilder sb = new StringBuilder();
            // Pick apart the OID
            byte x = (byte)(aOID[0] / 40);
            byte y = (byte)(aOID[0] % 40);
            if (x > 2)
            {
                // Handle special case for large y if x = 2
                y += (byte)((x - 2) * 40);
                x = 2;
            }
            sb.Append(x.ToString(CultureInfo.InvariantCulture));
            sb.Append(".");
            sb.Append(y.ToString(CultureInfo.InvariantCulture));
            ulong val = 0;
            for (x = 1; x < aOID.Length; x++)
            {
                val = ((val << 7) | ((byte)(aOID[x] & 0x7F)));
                if (!((aOID[x] & 0x80) == 0x80))
                {
                    sb.Append(".");
                    sb.Append(val.ToString(CultureInfo.InvariantCulture));
                    val = 0;
                }
            }
            return sb.ToString();
        }
		protected override void Decode () 
		{
			ASN1 sequence = new ASN1 (extnValue.Value);
			if (sequence.Tag != 0x04)
				throw new ArgumentException ("Invalid SubjectKeyIdentifier extension");
			ski = sequence.Value;
		}
예제 #6
0
		public GeneralNames (ASN1 sequence)
		{
			for (int i = 0; i < sequence.Count; i++) {
				switch (sequence[i].Tag) {
				case 0x81: // rfc822Name			[1]	IA5String
					if (rfc822Name == null)
						rfc822Name = new ArrayList ();
					rfc822Name.Add (Encoding.ASCII.GetString (sequence[i].Value));
					break;
				case 0x82: // dNSName				[2]     IA5String
					if (dnsName == null)
						dnsName = new ArrayList ();
					dnsName.Add (Encoding.ASCII.GetString (sequence[i].Value));
					break;
				case 0x84: // directoryName			[4]     Name
				case 0xA4:
					if (directoryNames == null)
						directoryNames = new ArrayList ();
					directoryNames.Add (X501.ToString (sequence[i][0]));
					break;
				case 0x86:  // uniformResourceIdentifier	[6]     IA5String
					if (uris == null)
						uris = new ArrayList ();
					uris.Add (Encoding.ASCII.GetString (sequence[i].Value));
					break;
				case 0x87: // iPAddress				[7]     OCTET STRING
					if (ipAddr == null)
						ipAddr = new ArrayList ();
					// TODO - Must find sample certificates
					break;
				default:
					break;
				}
			}
		}
예제 #7
0
		static public ASN1 Attribute (string oid, ASN1 value) 
		{
			ASN1 attr = new ASN1 (0x30);
			attr.Add (ASN1Convert.FromOid (oid));
			ASN1 aset = attr.Add (new ASN1 (0x31));
			aset.Add (value);
			return attr;
		}
		protected override void Encode () 
		{
			if (extnValue == null) {
				extnValue = new ASN1 (0x30);
				foreach (string oid in keyPurpose) {
					extnValue.Add (ASN1Convert.FromOid (oid));
				}
			}
		}
예제 #9
0
		protected override void Encode () 
		{
			ASN1 seq = new ASN1 (0x30);
			foreach (string oid in keyPurpose) {
				seq.Add (ASN1Convert.FromOid (oid));
			}

			extnValue = new ASN1 (0x04);
			extnValue.Add (seq);
		}
		public void ConvertDateTimeInvalidButExistingFormat () 
		{
			string nosecs = "9912312359Z"; 
			ASN1 dt = new ASN1 (0x18, Encoding.ASCII.GetBytes (nosecs));
			DateTime actual = ASN1Convert.ToDateTime (dt);
#if NET_2_0
			Assert.AreEqual (DateTimeKind.Utc, actual.Kind, "Kind");
#endif
			Assert.AreEqual (nosecs, actual.ToUniversalTime ().ToString ("yyMMddHHmm") + "Z", "DateTime");
		}
		protected override void Decode () 
		{
			keyPurpose = new ArrayList ();
			ASN1 sequence = new ASN1 (extnValue.Value);
			if (sequence.Tag != 0x30)
				throw new ArgumentException ("Invalid ExtendedKeyUsage extension");
			// for every policy OID
			for (int i=0; i < sequence.Count; i++)
				keyPurpose.Add (ASN1Convert.ToOid (sequence [i]));
		}
		protected override void Encode ()
		{
			if (ski == null) {
				throw new InvalidOperationException ("Invalid SubjectKeyIdentifier extension");
			}

			var seq = new ASN1 (0x04, ski);
			extnValue = new ASN1 (0x04);
			extnValue.Add (seq);
		}
예제 #13
0
		public X509Extension (ASN1 asn1) 
		{
			if ((asn1.Tag != 0x30) || (asn1.Count < 2))
				throw new ArgumentException ("Invalid X.509 extension");
			if (asn1[0].Tag != 0x06)
				throw new ArgumentException ("Invalid X.509 extension");
			extnOid = ASN1Convert.ToOid (asn1 [0]);
			extnCritical = ((asn1[1].Tag == 0x01) && (asn1[1].Value[0] == 0xFF));
			extnValue = asn1 [asn1.Count - 1]; // last element
			Decode ();
		}
예제 #14
0
		public X509Extension (X509Extension extension) : this () 
		{
			if (extension == null)
				throw new ArgumentNullException ("extension");
			if ((extension.Value.Tag != 0x04) || (extension.Value.Count != 0))
				throw new ArgumentException ("Invalid extension");
			extnOid = extension.Oid;
			extnCritical = extension.Critical;
			extnValue = extension.Value;
			Decode ();
		}
		public X509ExtensionCollection (ASN1 asn1) : this ()
		{
			readOnly = true;
			if (asn1 == null)
				return;
			if (asn1.Tag != 0x30)
				throw new Exception ("Invalid extensions format");
			for (int i=0; i < asn1.Count; i++) {
				X509Extension extension = new X509Extension (asn1 [i]);
				InnerList.Add (extension);
			}
		}
예제 #16
0
		static public string ToString (ASN1 seq) 
		{
			StringBuilder sb = new StringBuilder ();
			for (int i = 0; i < seq.Count; i++) {
				ASN1 entry = seq [i];
				AppendEntry (sb, entry, true);

				// separator (not on last iteration)
				if (i < seq.Count - 1)
					sb.Append (", ");
			}
			return sb.ToString ();
		}
		protected override void Decode () 
		{
			ASN1 sequence = new ASN1 (extnValue.Value);
			if (sequence.Tag != 0x30)
				throw new ArgumentException ("Invalid AuthorityKeyIdentifier extension");
			for (int i=0; i < sequence.Count; i++) {
				ASN1 el = sequence [i];
				switch (el.Tag) {
					case 0x80:
						aki = el.Value;
						break;
					default:
						// don't throw on stuff we don't yet support
						// e.g. authorityCertIssuer/authorityCertSerialNumber
						break;
				}
			}
		}
		protected override void Decode () 
		{
			ASN1 sequence = new ASN1 (extnValue.Value);
			if (sequence.Tag != 0x30)
				throw new ArgumentException ("Invalid PrivateKeyUsagePeriod extension");
			for (int i=0; i < sequence.Count; i++) {
				switch (sequence [i].Tag) {
					case 0x80:
						notBefore = ASN1Convert.ToDateTime (sequence [i]);
						break;
					case 0x81:
						notAfter = ASN1Convert.ToDateTime (sequence [i]);
						break;
					default:
						throw new ArgumentException ("Invalid PrivateKeyUsagePeriod extension");
				}
			}
		}
		protected override void Decode () 
		{
			ASN1 sequence = new ASN1 (extnValue.Value);
			if (sequence.Tag != 0x30)
				throw new ArgumentException ("Invalid AuthorityKeyIdentifier extension");
			for (int i=0; i < sequence.Count; i++) {
				ASN1 el = sequence [i];
				switch (el.Tag) {
					case 0x80:
						aki = el.Value;
						break;
					case 0x81:
					case 0x82:
					default:
						throw new ArgumentException ("Invalid AuthorityKeyIdentifier extension");
				}
			}
		}
		protected override void Decode () 
		{
			// default values
			cA = false;
			pathLenConstraint = 0; // no constraint

			ASN1 sequence = new ASN1 (extnValue.Value);
			if (sequence.Tag != 0x30)
				throw new ArgumentException ("Invalid BasicConstraints extension");
			int n = 0;
			ASN1 a = sequence [n++];
			if ((a != null) && (a.Tag == 0x01)) {
				cA = (a.Value [0] == 0xFF);
				a = sequence [n++];
			}
			if ((a != null) && (a.Tag == 0x02))
				pathLenConstraint = ASN1Convert.ToInt32 (a);
		}
예제 #21
0
		protected override void Decode () 
		{
			ASN1 seq = new ASN1 (extnValue.Value);
			if (seq.Tag != 0x30)
				throw new ArgumentException ("Invalid KeyAttributesExtension extension");
			int n = 0;
			// check for KeyIdentifier
			if (n < seq.Count) {
				ASN1 item = seq [n];
				if (item.Tag == 0x04) {
					n++;
					keyId = item.Value;
				}
			}
			// check for KeyUsage
			if (n < seq.Count) {
				ASN1 item = seq [n];
				if (item.Tag == 0x03) {
					n++;
					int i = 1; // byte zero has the number of unused bits (ASN1's BITSTRING)
					while (i < item.Value.Length)
						kubits = (kubits << 8) + item.Value [i++];
				}
			}
			// check for PrivateKeyValidity
			if (n < seq.Count) {
				ASN1 item = seq [n];
				if (item.Tag == 0x30) {
					int i = 0;
					if (i < item.Count) {
						ASN1 dt = item [i];
						if (dt.Tag == 0x81) {
							i++;
							notBefore = ASN1Convert.ToDateTime (dt);
						}
					}
					if (i < item.Count) {
						ASN1 dt = item [i];
						if (dt.Tag == 0x82)
							notAfter = ASN1Convert.ToDateTime (dt);
					}
				}
			}
		}
예제 #22
0
		public GeneralNames (string[] rfc822s, string[] dnsNames, string[] ipAddresses, string[] uris)
		{
			// This is an extension
			asn = new ASN1 (0x30);

			if (rfc822s != null) {
				rfc822Name = new ArrayList ();
				foreach (string rfc822 in rfc822s) {
					asn.Add (new ASN1 (0x81, Encoding.ASCII.GetBytes (rfc822)));
					rfc822Name.Add (rfc822s);
				}
			}

			if (dnsNames != null) {
				dnsName = new ArrayList ();
				foreach (string dnsname in dnsNames) {
					asn.Add (new ASN1 (0x82, Encoding.ASCII.GetBytes (dnsname)));
					dnsName.Add(dnsname);
				}
			}

			if (ipAddresses != null) {
				ipAddr = new ArrayList ();
				foreach (string ipaddress in ipAddresses) {
					string[] parts = ipaddress.Split ('.', ':');
					byte[] bytes = new byte[parts.Length];
					for (int i = 0; i < parts.Length; i++) {
						bytes[i] = Byte.Parse (parts[i]);
					}
					asn.Add (new ASN1 (0x87, bytes));
					ipAddr.Add (ipaddress);
				}
			}

			if (uris != null) {
				this.uris = new ArrayList();
				foreach (string uri in uris) {
					asn.Add (new ASN1 (0x86, Encoding.ASCII.GetBytes (uri)));
					this.uris.Add (uri);
				}
			}
		}
예제 #23
0
        private void AddRecordNodes(ASN1 asn, TreeNode parentNode)
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte b in asn.Tag)
            {
                sb.AppendFormat("{0:X2}", b);
            }

            TreeNode node = new TreeNode(sb.ToString());
            node.Tag = asn;
            node.ImageIndex = 6;
            node.SelectedImageIndex = 6;
            parentNode.Nodes.Add(node);

            if (asn.Count > 0)
            {
                foreach (ASN1 a in asn)
                {
                    AddRecordNodes(a, node);
                }
            }
        }
예제 #24
0
		static public ASN1 FromInt32 (Int32 value) 
		{
			byte[] integer = BitConverterLE.GetBytes (value);
			Array.Reverse (integer);
			int x = 0;
			while ((x < integer.Length) && (integer [x] == 0x00))
				x++;
			ASN1 asn1 = new ASN1 (0x02);
			switch (x) {
			case 0:
				asn1.Value = integer;
				break;
			case 4:
				asn1.Value = new byte [1];
				break;
			default:
				byte[] smallerInt = new byte [4 - x];
				Buffer.BlockCopy (integer, x, smallerInt, 0, smallerInt.Length);
				asn1.Value = smallerInt;
				break;
			}
			return asn1;
		}
예제 #25
0
  ///
  /// SEQUENCE (a)
  ///  +- INTEGER (V)              // Version - 0 (v1998)
  ///  +- SEQUENCE (b)
  ///  |   +- OID (oid)            // 1.2.840.113549.1.1.1
  ///  |   +- Nil (c)
  ///  +- OCTETSTRING(PRVKY) (os)  // Private Key Parameter
  ///
  ///  However, OCTETSTRING(PRVKY) wraps
  ///    SEQUENCE(
  ///      INTEGER(0)              // Version - 0 (v1998)
  ///      INTEGER(N)
  ///      INTEGER(E)
  ///      INTEGER(D)
  ///      INTEGER(P)
  ///      INTEGER(Q)
  ///      INTEGER(DP)
  ///      INTEGER(DQ)
  ///      INTEGER(InvQ)
  ///    )
  public static byte[] RSAKeyToASN1(RSAParameters PrivateKey) {
    ASN1 v = ASN1Convert.FromUnsignedBigInteger(new byte[] {0});

    ASN1 b = PKCS7.AlgorithmIdentifier ("1.2.840.113549.1.1.1");

    ASN1 os = new ASN1(0x30);
    os.Add(ASN1Convert.FromUnsignedBigInteger(new byte[] {0}));
    os.Add(ASN1Convert.FromUnsignedBigInteger(PrivateKey.Modulus));
    os.Add(ASN1Convert.FromUnsignedBigInteger(PrivateKey.Exponent));
    os.Add(ASN1Convert.FromUnsignedBigInteger(PrivateKey.D));
    os.Add(ASN1Convert.FromUnsignedBigInteger(PrivateKey.P));
    os.Add(ASN1Convert.FromUnsignedBigInteger(PrivateKey.Q));
    os.Add(ASN1Convert.FromUnsignedBigInteger(PrivateKey.DP));
    os.Add(ASN1Convert.FromUnsignedBigInteger(PrivateKey.DQ));
    os.Add(ASN1Convert.FromUnsignedBigInteger(PrivateKey.InverseQ));

    ASN1 pem = new ASN1(0x30);
    pem.Add(v);
    pem.Add(b);
    // Make this into an OCTET string
    pem.Add(new ASN1(0x04, os.GetBytes()));
    return pem.GetBytes();
  }
예제 #26
0
		public X509Extension (ASN1 asn1) 
		{
			if ((asn1.Tag != 0x30) || (asn1.Count < 2))
				throw new ArgumentException (Locale.GetText ("Invalid X.509 extension."));
			if (asn1[0].Tag != 0x06)
				throw new ArgumentException (Locale.GetText ("Invalid X.509 extension."));

			extnOid = ASN1Convert.ToOid (asn1[0]);
			extnCritical = ((asn1[1].Tag == 0x01) && (asn1[1].Value[0] == 0xFF));
			// last element is an octet string which may need to be decoded
			extnValue = asn1 [asn1.Count - 1];
			if ((extnValue.Tag == 0x04) && (extnValue.Length > 0) && (extnValue.Count == 0)) {
				try {
					ASN1 encapsulated = new ASN1 (extnValue.Value);
					extnValue.Value = null;
					extnValue.Add (encapsulated);
				}
				catch {
					// data isn't ASN.1
				}
			}
			Decode ();
		}
예제 #27
0
        public static ASN1 ToAsn1(RSA rsa)
        {
            EnsureNotNull(rsa, "rsa");

            ASN1 asn = new ASN1(0x30);
            ASN1 asnOid = new ASN1(0x30);

            // {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1) rsaEncryption(1)}
            // http://www.oid-info.com/get/1.2.840.113549.1.1.1
            asnOid.Add(ASN1Convert.FromOid("1.2.840.113549.1.1.1"));

            asnOid.Add(new ASN1(0x05));
            asn.Add(asnOid);

            ASN1 asnBits = new ASN1(0x03, new byte[1]);
            byte[] intermediate = ToAsn1Key(rsa).GetBytes();
            byte[] key = new byte[intermediate.Length + 1];
            intermediate.CopyTo(key, 1);
            asnBits.Value = key;

            asn.Add(asnBits);

            return asn;
        }
예제 #28
0
		public X500DistinguishedName (string distinguishedName, X500DistinguishedNameFlags flag)
		{
			if (distinguishedName == null)
				throw new ArgumentNullException ("distinguishedName");
			if ((flag != 0) && ((flag & AllFlags) == 0))
				throw new ArgumentException ("flag");

			Oid = new Oid ();
			if (distinguishedName.Length == 0) {
				// empty (0x00) ASN.1 sequence (0x30)
				RawData = new byte [2] { 0x30, 0x00 };
				DecodeRawData ();
			} else {
				var dn = MX.X501.FromString (distinguishedName);
				if ((flag & X500DistinguishedNameFlags.Reversed) != 0) {
					ASN1 rdn = new ASN1 (0x30);
					for (int i = dn.Count - 1; i >= 0; i--)	
						rdn.Add (dn [i]);
					dn = rdn;
				}
				RawData = dn.GetBytes ();
				if (flag == X500DistinguishedNameFlags.None)
					name = distinguishedName;
				else
					name = Decode (flag);
			}
		}
예제 #29
0
		// decode the DN using the (byte[]) RawData
		private void DecodeRawData ()
		{
			if ((RawData == null) || (RawData.Length < 3)) {
				name = String.Empty;
				return;
			}

			ASN1 sequence = new ASN1 (RawData);
			name = MX.X501.ToString (sequence, true, ", ", true);
		}
예제 #30
0
		public string Decode (X500DistinguishedNameFlags flag)
		{
			if ((flag != 0) && ((flag & AllFlags) == 0))
				throw new ArgumentException ("flag");

			if (RawData.Length == 0)
				return String.Empty;

			// Mono.Security reversed isn't the same as fx 2.0 (which is the reverse of 1.x)
			bool reversed = ((flag & X500DistinguishedNameFlags.Reversed) != 0);
			bool quotes = ((flag & X500DistinguishedNameFlags.DoNotUseQuotes) == 0);
			string separator = GetSeparator (flag);

			ASN1 rdn = new ASN1 (RawData);
			return MX.X501.ToString (rdn, reversed, separator, quotes);
		}
예제 #31
0
        static public DateTime ToDateTime(ASN1 time)
        {
            if (time == null)
            {
                throw new ArgumentNullException("time");
            }

            string t = Encoding.ASCII.GetString(time.Value);
            // to support both UTCTime and GeneralizedTime (and not so common format)
            string mask = null;
            int    year;

#if !NET_2_0
            bool utc = true;
#endif
            switch (t.Length)
            {
            case 11:
                // illegal format, still it's supported for compatibility
                mask = "yyMMddHHmmZ";
                break;

            case 13:
                // RFC3280: 4.1.2.5.1  UTCTime
                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
                // interpreted as 20YY.
                if (year >= 50)
                {
                    t = "19" + t;
                }
                else
                {
                    t = "20" + t;
                }
                mask = "yyyyMMddHHmmssZ";
                break;

            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";
#if !NET_2_0
                utc = false;
#endif
                break;
            }
#if NET_2_0
            return(DateTime.ParseExact(t, mask, null, DateTimeStyles.AdjustToUniversal));
#else
            DateTime result = DateTime.ParseExact(t, mask, null);
            if (utc)
            {
                return(result);
            }
            return(result.ToUniversalTime());
#endif
        }