Example #1
0
		static public string ToString (ASN1 seq, bool reversed, string separator, bool quotes)
		{
			StringBuilder sb = new StringBuilder ();

			if (reversed) {
				for (int i = seq.Count - 1; i >= 0; i--) {
					ASN1 entry = seq [i];
					AppendEntry (sb, entry, quotes);

					// separator (not on last iteration)
					if (i > 0)
						sb.Append (separator);
				}
			} else {
				for (int i = 0; i < seq.Count; i++) {
					ASN1 entry = seq [i];
					AppendEntry (sb, entry, quotes);

					// separator (not on last iteration)
					if (i < seq.Count - 1)
						sb.Append (separator);
				}
			}
			return sb.ToString ();
		}
Example #2
0
		static public KeyInfo GetType (byte[] data) 
		{
			if (data == null)
				throw new ArgumentNullException ("data");

			KeyInfo ki = KeyInfo.Unknown;
			try {
				ASN1 top = new ASN1 (data);
				if ((top.Tag == 0x30) && (top.Count > 0)) {
					ASN1 firstLevel = top [0];
					switch (firstLevel.Tag) {
						case 0x02:
							ki = KeyInfo.PrivateKey;
							break;
						case 0x30:
							ki = KeyInfo.EncryptedPrivateKey;
							break;
					}
				}
			}
			catch {
				throw new CryptographicException ("invalid ASN.1 data");
			}
			return ki;
		}
Example #3
0
		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);
			}
		}
Example #4
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 ();
		}
Example #5
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;
		}
Example #6
0
		static private void AppendEntry (StringBuilder sb, ASN1 entry, bool quotes)
		{
			// multiple entries are valid
			for (int k = 0; k < entry.Count; k++) {
				ASN1 pair = entry [k];
				ASN1 s = pair [1];
				if (s == null)
					continue;

				ASN1 poid = pair [0];
				if (poid == null)
					continue;

				if (poid.CompareValue (countryName))
					sb.Append ("C=");
				else if (poid.CompareValue (organizationName))
					sb.Append ("O=");
				else if (poid.CompareValue (organizationalUnitName))
					sb.Append ("OU=");
				else if (poid.CompareValue (commonName))
					sb.Append ("CN=");
				else if (poid.CompareValue (localityName))
					sb.Append ("L=");
				else if (poid.CompareValue (stateOrProvinceName))
					sb.Append ("S=");	// NOTE: RFC2253 uses ST=
				else if (poid.CompareValue (streetAddress))
					sb.Append ("STREET=");
				else if (poid.CompareValue (domainComponent))
					sb.Append ("DC=");
				else if (poid.CompareValue (userid))
					sb.Append ("UID=");
				else if (poid.CompareValue (email))
					sb.Append ("E=");	// NOTE: Not part of RFC2253
				else if (poid.CompareValue (dnQualifier))
					sb.Append ("dnQualifier=");
				else if (poid.CompareValue (title))
					sb.Append ("T=");
				else if (poid.CompareValue (surname))
					sb.Append ("SN=");
				else if (poid.CompareValue (givenName))
					sb.Append ("G=");
				else if (poid.CompareValue (initial))
					sb.Append ("I=");
				else {
					// unknown OID
					sb.Append ("OID.");	// NOTE: Not present as RFC2253
					sb.Append (ASN1Convert.ToOid (poid));
					sb.Append ("=");
				}

				string sValue = null;
				// 16bits or 8bits string ? TODO not complete (+special chars!)
				if (s.Tag == 0x1E) {
					// BMPSTRING
					StringBuilder sb2 = new StringBuilder ();
					for (int j = 1; j < s.Value.Length; j += 2)
						sb2.Append ((char)s.Value[j]);
					sValue = sb2.ToString ();
				} else {
					if (s.Tag == 0x14)
						sValue = Encoding.UTF7.GetString (s.Value);
					else
						sValue = Encoding.UTF8.GetString (s.Value);
					// in some cases we must quote (") the value
					// Note: this doesn't seems to conform to RFC2253
					char[] specials = { ',', '+', '"', '\\', '<', '>', ';' };
					if (quotes) {
						if ((sValue.IndexOfAny (specials, 0, sValue.Length) > 0) ||
						    sValue.StartsWith (" ") || (sValue.EndsWith (" ")))
							sValue = "\"" + sValue + "\"";
					}
				}

				sb.Append (sValue);

				// separator (not on last iteration)
				if (k < entry.Count - 1)
					sb.Append (", ");
			}
		}
Example #7
0
		public ASN1 Add (ASN1 asn1) 
		{
			if (asn1 != null) {
				if (elist == null)
					elist = new ArrayList ();
				elist.Add (asn1);
			}
			return asn1;
		}
Example #8
0
		private byte[] UniqueIdentifier (byte[] id) 
		{
			// UniqueIdentifier  ::=  BIT STRING
			ASN1 uid = new ASN1 (0x03);
			// first byte in a BITSTRING is the number of unused bits in the first byte
			byte[] v = new byte [id.Length + 1];
			Buffer.BlockCopy (id, 0, v, 1, id.Length);
			uid.Value = v;
			return uid.GetBytes ();
		}
Example #9
0
			// DSA only encode it's X private key inside an ASN.1 INTEGER (Hint: Tag == 0x02)
			// which isn't enough for rebuilding the keypair. The other parameters
			// can be found (98% of the time) in the X.509 certificate associated
			// with the private key or (2% of the time) the parameters are in it's
			// issuer X.509 certificate (not supported in the .NET framework).
			static public DSA DecodeDSA (byte[] privateKey, DSAParameters dsaParameters) 
			{
				ASN1 pvk = new ASN1 (privateKey);
				if (pvk.Tag != 0x02)
					throw new CryptographicException ("invalid private key format");

				// X is ALWAYS 20 bytes (no matter if the key length is 512 or 1024 bits)
				dsaParameters.X = Normalize (pvk.Value, 20);
				DSA dsa = DSA.Create ();
				dsa.ImportParameters (dsaParameters);
				return dsa;
			}
Example #10
0
			/*
			 * RSAPrivateKey ::= SEQUENCE {
			 *	version           Version, 
			 *	modulus           INTEGER,  -- n
			 *	publicExponent    INTEGER,  -- e
			 *	privateExponent   INTEGER,  -- d
			 *	prime1            INTEGER,  -- p
			 *	prime2            INTEGER,  -- q
			 *	exponent1         INTEGER,  -- d mod (p-1)
			 *	exponent2         INTEGER,  -- d mod (q-1) 
			 *	coefficient       INTEGER,  -- (inverse of q) mod p
			 *	otherPrimeInfos   OtherPrimeInfos OPTIONAL 
			 * }
			 */
			static public RSA DecodeRSA (byte[] keypair) 
			{
				ASN1 privateKey = new ASN1 (keypair);
				if (privateKey.Tag != 0x30)
					throw new CryptographicException ("invalid private key format");

				ASN1 version = privateKey [0];
				if (version.Tag != 0x02)
					throw new CryptographicException ("missing version");

				if (privateKey.Count < 9)
					throw new CryptographicException ("not enough key parameters");

				RSAParameters param = new RSAParameters ();
				// note: MUST remove leading 0 - else MS wont import the key
				param.Modulus = RemoveLeadingZero (privateKey [1].Value);
				int keysize = param.Modulus.Length;
				int keysize2 = (keysize >> 1); // half-size
				// size must be normalized - else MS wont import the key
				param.D = Normalize (privateKey [3].Value, keysize);
				param.DP = Normalize (privateKey [6].Value, keysize2);
				param.DQ = Normalize (privateKey [7].Value, keysize2);
				param.Exponent = RemoveLeadingZero (privateKey [2].Value);
				param.InverseQ = Normalize (privateKey [8].Value, keysize2);
				param.P = Normalize (privateKey [4].Value, keysize2);
				param.Q = Normalize (privateKey [5].Value, keysize2);

				RSA rsa = null;
				try {
					rsa = RSA.Create ();
					rsa.ImportParameters (param);
				}
				catch (CryptographicException) {
                    // this may cause problem when this code is run under
                    // the SYSTEM identity on Windows (e.g. ASP.NET). See
                    // http://bugzilla.ximian.com/show_bug.cgi?id=77559
                    CspParameters csp = new CspParameters();
                    csp.Flags = CspProviderFlags.UseMachineKeyStore;
                    rsa = new RSACryptoServiceProvider(csp);
                    rsa.ImportParameters(param);
                }
                return rsa;
			}
Example #11
0
			// methods

			private void Decode (byte[] data) 
			{
				ASN1 privateKeyInfo = new ASN1 (data);
				if (privateKeyInfo.Tag != 0x30)
					throw new CryptographicException ("invalid PrivateKeyInfo");

				ASN1 version = privateKeyInfo [0];
				if (version.Tag != 0x02)
					throw new CryptographicException ("invalid version");
				_version = version.Value [0];

				ASN1 privateKeyAlgorithm = privateKeyInfo [1];
				if (privateKeyAlgorithm.Tag != 0x30)
					throw new CryptographicException ("invalid algorithm");
				
				ASN1 algorithm = privateKeyAlgorithm [0];
				if (algorithm.Tag != 0x06)
					throw new CryptographicException ("missing algorithm OID");
				_algorithm = ASN1Convert.ToOid (algorithm);

				ASN1 privateKey = privateKeyInfo [2];
				_key = privateKey.Value;

				// attributes [0] IMPLICIT Attributes OPTIONAL
				if (privateKeyInfo.Count > 3) {
					ASN1 attributes = privateKeyInfo [3];
					for (int i=0; i < attributes.Count; i++) {
						_list.Add (attributes [i]);
					}
				}
			}
Example #12
0
		private ASN1 SecretBagSafeBag (byte[] secret, IDictionary attributes) 
		{
			ASN1 safeBag = new ASN1 (0x30);
			safeBag.Add (ASN1Convert.FromOid (secretBag));
			ASN1 bagValue = new ASN1 (0x80, secret);
			safeBag.Add (bagValue);

			if (attributes != null) {
				ASN1 bagAttributes = new ASN1 (0x31);
				IDictionaryEnumerator de = attributes.GetEnumerator ();

				while (de.MoveNext ()) {
					string oid = (string)de.Key;
					switch (oid) {
					case PKCS9.friendlyName:
						ArrayList names = (ArrayList)de.Value;
						if (names.Count > 0) {
							ASN1 pkcs12Attribute = new ASN1 (0x30);
							pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName));
							ASN1 attrValues = new ASN1 (0x31);
							foreach (byte[] name in names) {
								ASN1 attrValue = new ASN1 (0x1e);
								attrValue.Value = name;
								attrValues.Add (attrValue);
							}
							pkcs12Attribute.Add (attrValues);
							bagAttributes.Add (pkcs12Attribute);
						}
						break;
					case PKCS9.localKeyId:
						ArrayList keys = (ArrayList)de.Value;
						if (keys.Count > 0) {
							ASN1 pkcs12Attribute = new ASN1 (0x30);
							pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId));
							ASN1 attrValues = new ASN1 (0x31);
							foreach (byte[] key in keys) {
								ASN1 attrValue = new ASN1 (0x04);
								attrValue.Value = key;
								attrValues.Add (attrValue);
							}
							pkcs12Attribute.Add (attrValues);
							bagAttributes.Add (pkcs12Attribute);
						}
						break;
					default:
						break;
					}
				}

				if (bagAttributes.Count > 0) {
					safeBag.Add (bagAttributes);
				}
			}

			return safeBag;
		}
Example #13
0
		public virtual byte[] Sign (DSA key) 
		{
			string oid = "1.2.840.10040.4.3";
			ASN1 tbs = ToBeSigned (oid);
			HashAlgorithm ha = HashAlgorithm.Create (hashName);
			if (!(ha is SHA1))
				throw new NotSupportedException ("Only SHA-1 is supported for DSA");
			byte[] hash = ha.ComputeHash (tbs.GetBytes ());

			DSASignatureFormatter dsa = new DSASignatureFormatter (key);
			dsa.SetHashAlgorithm (hashName);
			byte[] rs = dsa.CreateSignature (hash);

			// split R and S
			byte[] r = new byte [20];
			Buffer.BlockCopy (rs, 0, r, 0, 20);
			byte[] s = new byte [20];
			Buffer.BlockCopy (rs, 20, s, 0, 20);
			ASN1 signature = new ASN1 (0x30);
			signature.Add (new ASN1 (0x02, r));
			signature.Add (new ASN1 (0x02, s));

			// dsaWithSha1 (1 2 840 10040 4 3)
			return Build (tbs, oid, signature.GetBytes ());
		}
Example #14
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;
			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";
					break;
			}
			return DateTime.ParseExact (t, mask, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
		}
Example #15
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 ();
		}
Example #16
0
		static public int ToInt32 (ASN1 asn1) 
		{
			if (asn1 == null)
				throw new ArgumentNullException ("asn1");
			if (asn1.Tag != 0x02)
				throw new FormatException ("Only integer can be converted");

			int x = 0;
			for (int i=0; i < asn1.Value.Length; i++)
				x = (x << 8) + asn1.Value [i];
			return x;
		}
Example #17
0
		protected override ASN1 ToBeSigned (string oid) 
		{
			// TBSCertificate
			ASN1 tbsCert = new ASN1 (0x30);

			if (version > 1) {
				// TBSCertificate / [0] Version DEFAULT v1,
				byte[] ver = { (byte)(version - 1) };
				ASN1 v = tbsCert.Add (new ASN1 (0xA0));
				v.Add (new ASN1 (0x02, ver));
			}

			// TBSCertificate / CertificateSerialNumber,
			tbsCert.Add (new ASN1 (0x02, sn));

			// TBSCertificate / AlgorithmIdentifier,
                        tbsCert.Add (PKCS7.AlgorithmIdentifier (oid));

			// TBSCertificate / Name
			tbsCert.Add (X501.FromString (issuer));

			// TBSCertificate / Validity
			ASN1 validity = tbsCert.Add (new ASN1 (0x30));
			// TBSCertificate / Validity / Time
			validity.Add (ASN1Convert.FromDateTime (notBefore));
			// TBSCertificate / Validity / Time
			validity.Add (ASN1Convert.FromDateTime (notAfter));

			// TBSCertificate / Name
			tbsCert.Add (X501.FromString (subject));

			// TBSCertificate / SubjectPublicKeyInfo
			tbsCert.Add (SubjectPublicKeyInfo ());
                        
			if (version > 1) {
				// TBSCertificate / [1]  IMPLICIT UniqueIdentifier OPTIONAL
				if (issuerUniqueID != null)
					tbsCert.Add (new ASN1 (0xA1, UniqueIdentifier (issuerUniqueID)));

				// TBSCertificate / [2]  IMPLICIT UniqueIdentifier OPTIONAL
				if (subjectUniqueID != null)
					tbsCert.Add (new ASN1 (0xA1, UniqueIdentifier (subjectUniqueID)));

				// TBSCertificate / [3]  Extensions OPTIONAL
				if ((version > 2) &&  (extensions.Count > 0))
					tbsCert.Add (new ASN1 (0xA3, extensions.GetBytes ()));
			}

			return tbsCert;
		}
Example #18
0
		static public ASN1 FromString (string rdn) 
		{
			if (rdn == null)
				throw new ArgumentNullException ("rdn");

			int pos = 0;
			ASN1 asn1 = new ASN1 (0x30);
			while (pos < rdn.Length) {
				X520.AttributeTypeAndValue atv = ReadAttribute (rdn, ref pos);
				atv.Value = ReadValue (rdn, ref pos);

				ASN1 sequence = new ASN1 (0x31);
				sequence.Add (atv.GetASN1 ());
				asn1.Add (sequence); 
			}
			return asn1;
		}
Example #19
0
		private byte[] Build (ASN1 tbs, string hashoid, byte[] signature) 
		{
			ASN1 builder = new ASN1 (0x30);
			builder.Add (tbs);
			builder.Add (PKCS7.AlgorithmIdentifier (hashoid));
			// first byte of BITSTRING is the number of unused bits in the first byte
			byte[] bitstring = new byte [signature.Length + 1];
			Buffer.BlockCopy (signature, 0, bitstring, 1, signature.Length);
			builder.Add (new ASN1 (0x03, bitstring));
			return builder.GetBytes ();
		}
Example #20
0
			internal ASN1 GetASN1 (byte encoding) 
			{
				byte encode = encoding;
				if (encode == 0xFF)
					encode = SelectBestEncoding ();
					
				ASN1 asn1 = new ASN1 (0x30);
				asn1.Add (ASN1Convert.FromOid (oid));
				switch (encode) {
					case 0x13:
						// PRINTABLESTRING
						asn1.Add (new ASN1 (0x13, Encoding.ASCII.GetBytes (attrValue)));
						break;
					case 0x16:
						// IA5STRING
						asn1.Add (new ASN1 (0x16, Encoding.ASCII.GetBytes (attrValue)));
						break;
					case 0x1E:
						// BMPSTRING
						asn1.Add (new ASN1 (0x1E, Encoding.BigEndianUnicode.GetBytes (attrValue)));
						break;
				}
				return asn1;
			}
Example #21
0
		// that's were the real job is!
		private void Parse (byte[] data) 
		{
			try {
				decoder = new ASN1 (data);
				// Certificate 
				if (decoder.Tag != 0x30)
					throw new CryptographicException (encoding_error);
				// Certificate / TBSCertificate
				if (decoder [0].Tag != 0x30)
					throw new CryptographicException (encoding_error);

				ASN1 tbsCertificate = decoder [0];

				int tbs = 0;
				// Certificate / TBSCertificate / Version
				ASN1 v = decoder [0][tbs];
				version = 1;			// DEFAULT v1
				if ((v.Tag == 0xA0) && (v.Count > 0)) {
					// version (optional) is present only in v2+ certs
					version += v [0].Value [0];	// zero based
					tbs++;
				}

				// Certificate / TBSCertificate / CertificateSerialNumber
				ASN1 sn = decoder [0][tbs++];
				if (sn.Tag != 0x02) 
					throw new CryptographicException (encoding_error);
				serialnumber = sn.Value;
				Array.Reverse (serialnumber, 0, serialnumber.Length);
		
				// Certificate / TBSCertificate / AlgorithmIdentifier
				tbs++;
				// ASN1 signatureAlgo = tbsCertificate.Element (tbs++, 0x30); 
		
				issuer = tbsCertificate.Element (tbs++, 0x30); 
				m_issuername = X501.ToString (issuer);
		
				ASN1 validity = tbsCertificate.Element (tbs++, 0x30);
				ASN1 notBefore = validity [0];
				m_from = ASN1Convert.ToDateTime (notBefore);
				ASN1 notAfter = validity [1];
				m_until = ASN1Convert.ToDateTime (notAfter);
		
				subject = tbsCertificate.Element (tbs++, 0x30);
				m_subject = X501.ToString (subject);
		
				ASN1 subjectPublicKeyInfo = tbsCertificate.Element (tbs++, 0x30);
		
				ASN1 algorithm = subjectPublicKeyInfo.Element (0, 0x30);
				ASN1 algo = algorithm.Element (0, 0x06);
				m_keyalgo = ASN1Convert.ToOid (algo);
				// parameters ANY DEFINED BY algorithm OPTIONAL
				// so we dont ask for a specific (Element) type and return DER
				ASN1 parameters = algorithm [1];
				m_keyalgoparams = ((algorithm.Count > 1) ? parameters.GetBytes () : null);
		
				ASN1 subjectPublicKey = subjectPublicKeyInfo.Element (1, 0x03); 
				// we must drop th first byte (which is the number of unused bits
				// in the BITSTRING)
				int n = subjectPublicKey.Length - 1;
				m_publickey = new byte [n];
				Buffer.BlockCopy (subjectPublicKey.Value, 1, m_publickey, 0, n);

				// signature processing
				byte[] bitstring = decoder [2].Value;
				// first byte contains unused bits in first byte
				signature = new byte [bitstring.Length - 1];
				Buffer.BlockCopy (bitstring, 1, signature, 0, signature.Length);

				algorithm = decoder [1];
				algo = algorithm.Element (0, 0x06);
				m_signaturealgo = ASN1Convert.ToOid (algo);
				parameters = algorithm [1];
				if (parameters != null)
					m_signaturealgoparams = parameters.GetBytes ();
				else
					m_signaturealgoparams = null;

				// Certificate / TBSCertificate / issuerUniqueID
				ASN1 issuerUID = tbsCertificate.Element (tbs, 0x81);
				if (issuerUID != null) {
					tbs++;
					issuerUniqueID = issuerUID.Value;
				}

				// Certificate / TBSCertificate / subjectUniqueID
				ASN1 subjectUID = tbsCertificate.Element (tbs, 0x82);
				if (subjectUID != null) {
					tbs++;
					subjectUniqueID = subjectUID.Value;
				}

				// Certificate / TBSCertificate / Extensions
				ASN1 extns = tbsCertificate.Element (tbs, 0xA3);
				if ((extns != null) && (extns.Count == 1))
					extensions = new X509ExtensionCollection (extns [0]);
				else
					extensions = new X509ExtensionCollection (null);

				// keep a copy of the original data
				m_encodedcert = (byte[]) data.Clone ();
			}
			catch (Exception ex) {
				throw new CryptographicException (encoding_error, ex);
			}
		}
Example #22
0
		public byte[] GetBytes () 
		{
			if (InnerList.Count < 1)
				return null;
			ASN1 sequence = new ASN1 (0x30);
			for (int i=0; i < InnerList.Count; i++) {
				X509Extension x = (X509Extension) InnerList [i];
				sequence.Add (x.ASN1);
			}
			return sequence.GetBytes ();
		}
Example #23
0
			public byte[] GetBytes () 
			{
				ASN1 privateKeyAlgorithm = new ASN1 (0x30);
				privateKeyAlgorithm.Add (ASN1Convert.FromOid (_algorithm));
				privateKeyAlgorithm.Add (new ASN1 (0x05)); // ASN.1 NULL

				ASN1 pki = new ASN1 (0x30);
				pki.Add (new ASN1 (0x02, new byte [1] { (byte) _version }));
				pki.Add (privateKeyAlgorithm);
				pki.Add (new ASN1 (0x04, _key));

				if (_list.Count > 0) {
					ASN1 attributes = new ASN1 (0xA0);
					foreach (ASN1 attribute in _list) {
						attributes.Add (attribute);
					}
					pki.Add (attributes);
				}

				return pki.GetBytes ();
			}
Example #24
0
			// Note: PKCS#8 doesn't define how to generate the key required for encryption
			// so you're on your own. Just don't try to copy the big guys too much ;)
			// Netscape:	http://www.cs.auckland.ac.nz/~pgut001/pubs/netscape.txt
			// Microsoft:	http://www.cs.auckland.ac.nz/~pgut001/pubs/breakms.txt
			public byte[] GetBytes ()
			{
				if (_algorithm == null)
					throw new CryptographicException ("No algorithm OID specified");

				ASN1 encryptionAlgorithm = new ASN1 (0x30);
				encryptionAlgorithm.Add (ASN1Convert.FromOid (_algorithm));

				// parameters ANY DEFINED BY algorithm OPTIONAL
				if ((_iterations > 0) || (_salt != null)) {
					ASN1 salt = new ASN1 (0x04, _salt);
					ASN1 iterations = ASN1Convert.FromInt32 (_iterations);

					ASN1 parameters = new ASN1 (0x30);
					parameters.Add (salt);
					parameters.Add (iterations);
					encryptionAlgorithm.Add (parameters);
				}

				// encapsulates EncryptedData into an OCTET STRING
				ASN1 encryptedData = new ASN1 (0x04, _data);

				ASN1 encryptedPrivateKeyInfo = new ASN1 (0x30);
				encryptedPrivateKeyInfo.Add (encryptionAlgorithm);
				encryptedPrivateKeyInfo.Add (encryptedData);

				return encryptedPrivateKeyInfo.GetBytes ();
			}
Example #25
0
			/*
			 * RSAPrivateKey ::= SEQUENCE {
			 *	version           Version, 
			 *	modulus           INTEGER,  -- n
			 *	publicExponent    INTEGER,  -- e
			 *	privateExponent   INTEGER,  -- d
			 *	prime1            INTEGER,  -- p
			 *	prime2            INTEGER,  -- q
			 *	exponent1         INTEGER,  -- d mod (p-1)
			 *	exponent2         INTEGER,  -- d mod (q-1) 
			 *	coefficient       INTEGER,  -- (inverse of q) mod p
			 *	otherPrimeInfos   OtherPrimeInfos OPTIONAL 
			 * }
			 */
			static public byte[] Encode (RSA rsa) 
			{
				RSAParameters param = rsa.ExportParameters (true);

				ASN1 rsaPrivateKey = new ASN1 (0x30);
				rsaPrivateKey.Add (new ASN1 (0x02, new byte [1] { 0x00 }));
				rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.Modulus));
				rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.Exponent));
				rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.D));
				rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.P));
				rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.Q));
				rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.DP));
				rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.DQ));
				rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.InverseQ));

				return rsaPrivateKey.GetBytes ();
			}
Example #26
0
		private ASN1 KeyBagSafeBag (AsymmetricAlgorithm aa, IDictionary attributes) 
		{
			PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo ();
			if (aa is RSA) {
				pki.Algorithm = "1.2.840.113549.1.1.1";
				pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((RSA)aa);
			}
			else if (aa is DSA) {
				pki.Algorithm = null;
				pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((DSA)aa);
			}
			else
				throw new CryptographicException ("Unknown asymmetric algorithm {0}", aa.ToString ());

			ASN1 safeBag = new ASN1 (0x30);
			safeBag.Add (ASN1Convert.FromOid (keyBag));
			ASN1 bagValue = new ASN1 (0xA0);
			bagValue.Add (new ASN1 (pki.GetBytes ()));
			safeBag.Add (bagValue);

			if (attributes != null) {
				ASN1 bagAttributes = new ASN1 (0x31);
				IDictionaryEnumerator de = attributes.GetEnumerator ();

				while (de.MoveNext ()) {
					string oid = (string)de.Key;
					switch (oid) {
					case PKCS9.friendlyName:
						ArrayList names = (ArrayList)de.Value;
						if (names.Count > 0) {
							ASN1 pkcs12Attribute = new ASN1 (0x30);
							pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName));
							ASN1 attrValues = new ASN1 (0x31);
							foreach (byte[] name in names) {
								ASN1 attrValue = new ASN1 (0x1e);
								attrValue.Value = name;
								attrValues.Add (attrValue);
							}
							pkcs12Attribute.Add (attrValues);
							bagAttributes.Add (pkcs12Attribute);
						}
						break;
					case PKCS9.localKeyId:
						ArrayList keys = (ArrayList)de.Value;
						if (keys.Count > 0) {
							ASN1 pkcs12Attribute = new ASN1 (0x30);
							pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId));
							ASN1 attrValues = new ASN1 (0x31);
							foreach (byte[] key in keys) {
								ASN1 attrValue = new ASN1 (0x04);
								attrValue.Value = key;
								attrValues.Add (attrValue);
							}
							pkcs12Attribute.Add (attrValues);
							bagAttributes.Add (pkcs12Attribute);
						}
						break;
					default:
						break;
					}
				}

				if (bagAttributes.Count > 0) {
					safeBag.Add (bagAttributes);
				}
			}

			return safeBag;
		}
Example #27
0
			// methods

			private void Decode (byte[] data) 
			{
				ASN1 encryptedPrivateKeyInfo = new ASN1 (data);
				if (encryptedPrivateKeyInfo.Tag != 0x30)
					throw new CryptographicException ("invalid EncryptedPrivateKeyInfo");

				ASN1 encryptionAlgorithm = encryptedPrivateKeyInfo [0];
				if (encryptionAlgorithm.Tag != 0x30)
					throw new CryptographicException ("invalid encryptionAlgorithm");
				ASN1 algorithm = encryptionAlgorithm [0];
				if (algorithm.Tag != 0x06)
					throw new CryptographicException ("invalid algorithm");
				_algorithm = ASN1Convert.ToOid (algorithm);
				// parameters ANY DEFINED BY algorithm OPTIONAL
				if (encryptionAlgorithm.Count > 1) {
					ASN1 parameters = encryptionAlgorithm [1];
					if (parameters.Tag != 0x30)
						throw new CryptographicException ("invalid parameters");

					ASN1 salt = parameters [0];
					if (salt.Tag != 0x04)
						throw new CryptographicException ("invalid salt");
					_salt = salt.Value;

					ASN1 iterationCount = parameters [1];
					if (iterationCount.Tag != 0x02)
						throw new CryptographicException ("invalid iterationCount");
					_iterations = ASN1Convert.ToInt32 (iterationCount);
				}

				ASN1 encryptedData = encryptedPrivateKeyInfo [1];
				if (encryptedData.Tag != 0x04)
					throw new CryptographicException ("invalid EncryptedData");
				_data = encryptedData.Value;
			}
Example #28
0
		/* SubjectPublicKeyInfo  ::=  SEQUENCE  {
		 *      algorithm            AlgorithmIdentifier,
		 *      subjectPublicKey     BIT STRING  }
		 */
		private ASN1 SubjectPublicKeyInfo () 
		{
			ASN1 keyInfo = new ASN1 (0x30);
			if (aa is RSA) {
				keyInfo.Add (PKCS7.AlgorithmIdentifier ("1.2.840.113549.1.1.1"));
				RSAParameters p = (aa as RSA).ExportParameters (false);
				/* RSAPublicKey ::= SEQUENCE {
				 *       modulus            INTEGER,    -- n
				 *       publicExponent     INTEGER  }  -- e
				 */
				ASN1 key = new ASN1 (0x30);
				key.Add (ASN1Convert.FromUnsignedBigInteger (p.Modulus));
				key.Add (ASN1Convert.FromUnsignedBigInteger (p.Exponent));
				keyInfo.Add (new ASN1 (UniqueIdentifier (key.GetBytes ())));
			}
			else if (aa is DSA) {
				DSAParameters p = (aa as DSA).ExportParameters (false);
				/* Dss-Parms  ::=  SEQUENCE  {
				 *       p             INTEGER,
				 *       q             INTEGER,
				 *       g             INTEGER  }
				 */
				ASN1 param = new ASN1 (0x30);
				param.Add (ASN1Convert.FromUnsignedBigInteger (p.P));
				param.Add (ASN1Convert.FromUnsignedBigInteger (p.Q));
				param.Add (ASN1Convert.FromUnsignedBigInteger (p.G));
				keyInfo.Add (PKCS7.AlgorithmIdentifier ("1.2.840.10040.4.1", param));
				ASN1 key = keyInfo.Add (new ASN1 (0x03));
				// DSAPublicKey ::= INTEGER  -- public key, y
				key.Add (ASN1Convert.FromUnsignedBigInteger (p.Y));
			}
			else
				throw new NotSupportedException ("Unknown Asymmetric Algorithm " + aa.ToString ());
			return keyInfo;
		}
Example #29
0
		// PKCS #1 v.2.1, Section 9.2
		// EMSA-PKCS1-v1_5-Encode
		public static byte[] Encode_v15 (HashAlgorithm hash, byte[] hashValue, int emLength) 
		{
			if (hashValue.Length != (hash.HashSize >> 3))
				throw new CryptographicException ("bad hash length for " + hash.ToString ());

			// DigestInfo ::= SEQUENCE {
			//	digestAlgorithm AlgorithmIdentifier,
			//	digest OCTET STRING
			// }
		
			byte[] t = null;

			string oid = CryptoConfig.MapNameToOID (hash.ToString ());
			if (oid != null)
			{
				ASN1 digestAlgorithm = new ASN1 (0x30);
				digestAlgorithm.Add (new ASN1 (CryptoConfig.EncodeOID (oid)));
				digestAlgorithm.Add (new ASN1 (0x05));		// NULL
				ASN1 digest = new ASN1 (0x04, hashValue);
				ASN1 digestInfo = new ASN1 (0x30);
				digestInfo.Add (digestAlgorithm);
				digestInfo.Add (digest);

				t = digestInfo.GetBytes ();
			}
			else
			{
				// There are no valid OID, in this case t = hashValue
				// This is the case of the MD5SHA hash algorithm
				t = hashValue;
			}

			Buffer.BlockCopy (hashValue, 0, t, t.Length - hashValue.Length, hashValue.Length);
	
			int PSLength = System.Math.Max (8, emLength - t.Length - 3);
			// PS = PSLength of 0xff
	
			// EM = 0x00 | 0x01 | PS | 0x00 | T
			byte[] EM = new byte [PSLength + t.Length + 3];
			EM [1] = 0x01;
			for (int i=2; i < PSLength + 2; i++)
				EM[i] = 0xff;
			Buffer.BlockCopy (t, 0, EM, PSLength + 3, t.Length);
	
			return EM;
		}
Example #30
0
		private void ReadSafeBag (ASN1 safeBag) 
		{
			if (safeBag.Tag != 0x30)
				throw new ArgumentException ("invalid safeBag");

			ASN1 bagId = safeBag [0];
			if (bagId.Tag != 0x06)
				throw new ArgumentException ("invalid safeBag id");

			ASN1 bagValue = safeBag [1];
			string oid = ASN1Convert.ToOid (bagId);
			switch (oid) {
				case keyBag:
					// NEED UNIT TEST
					AddPrivateKey (new PKCS8.PrivateKeyInfo (bagValue.Value));
					break;
				case pkcs8ShroudedKeyBag:
					PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value);
					byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData);
					AddPrivateKey (new PKCS8.PrivateKeyInfo (decrypted));
					Array.Clear (decrypted, 0, decrypted.Length);
					break;
				case certBag:
					PKCS7.ContentInfo cert = new PKCS7.ContentInfo (bagValue.Value);
					if (cert.ContentType != x509Certificate)
						throw new NotSupportedException ("unsupport certificate type");
					X509Certificate x509 = new X509Certificate (cert.Content [0].Value);
					_certs.Add (x509);
					break;
				case crlBag:
					// TODO
					break;
				case secretBag: 
					byte[] secret = bagValue.Value;
					_secretBags.Add(secret);
					break;
				case safeContentsBag:
					// TODO - ? recurse ?
					break;
				default:
					throw new ArgumentException ("unknown safeBag oid");
			}

			if (safeBag.Count > 2) {
				ASN1 bagAttributes = safeBag [2];
				if (bagAttributes.Tag != 0x31)
					throw new ArgumentException ("invalid safeBag attributes id");

				for (int i = 0; i < bagAttributes.Count; i++) {
					ASN1 pkcs12Attribute = bagAttributes[i];
						
					if (pkcs12Attribute.Tag != 0x30)
						throw new ArgumentException ("invalid PKCS12 attributes id");

					ASN1 attrId = pkcs12Attribute [0];
					if (attrId.Tag != 0x06)
						throw new ArgumentException ("invalid attribute id");
						
					string attrOid = ASN1Convert.ToOid (attrId);

					ASN1 attrValues = pkcs12Attribute[1];
					for (int j = 0; j < attrValues.Count; j++) {
						ASN1 attrValue = attrValues[j];

						switch (attrOid) {
						case PKCS9.friendlyName:
							if (attrValue.Tag != 0x1e)
								throw new ArgumentException ("invalid attribute value id");
							break;
						case PKCS9.localKeyId:
							if (attrValue.Tag != 0x04)
								throw new ArgumentException ("invalid attribute value id");
							break;
						default:
							// Unknown OID -- don't check Tag
							break;
						}
					}
				}
			}

			_safeBags.Add (new SafeBag(oid, safeBag));
		}