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; }
internal X509CrlEntry (ASN1 entry) { sn = entry [0].Value; Array.Reverse (sn); revocationDate = ASN1Convert.ToDateTime (entry [1]); extensions = new X509ExtensionCollection (entry [2]); }
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(); }
private bool VerifyCounterSignature (PKCS7.SignerInfo cs, byte[] signature) { // SEQUENCE { // INTEGER 1 if (cs.Version != 1) return false; // SEQUENCE { // SEQUENCE { string contentType = null; ASN1 messageDigest = null; for (int i=0; i < cs.AuthenticatedAttributes.Count; i++) { // SEQUENCE { // OBJECT IDENTIFIER ASN1 attr = (ASN1) cs.AuthenticatedAttributes [i]; string oid = ASN1Convert.ToOid (attr[0]); switch (oid) { case "1.2.840.113549.1.9.3": // contentType contentType = ASN1Convert.ToOid (attr[1][0]); break; case "1.2.840.113549.1.9.4": // messageDigest messageDigest = attr[1][0]; break; case "1.2.840.113549.1.9.5": // SEQUENCE { // OBJECT IDENTIFIER // signingTime (1 2 840 113549 1 9 5) // SET { // UTCTime '030124013651Z' // } // } timestamp = ASN1Convert.ToDateTime (attr[1][0]); break; default: break; } } if (contentType != PKCS7.Oid.data) return false; // verify message digest if (messageDigest == null) return false; // TODO: must be read from the ASN.1 structure string hashName = null; switch (messageDigest.Length) { case 16: hashName = "MD5"; break; case 20: hashName = "SHA1"; break; } HashAlgorithm ha = HashAlgorithm.Create (hashName); if (!messageDigest.CompareValue (ha.ComputeHash (signature))) return false; // verify signature byte[] counterSignature = cs.Signature; // change to SET OF (not [0]) as per PKCS #7 1.5 ASN1 aa = new ASN1 (0x31); foreach (ASN1 a in cs.AuthenticatedAttributes) aa.Add (a); byte[] p7hash = ha.ComputeHash (aa.GetBytes ()); // we need to try all certificates string issuer = cs.IssuerName; byte[] serial = cs.SerialNumber; foreach (X509Certificate x509 in coll) { if (CompareIssuerSerial (issuer, serial, x509)) { if (x509.PublicKey.Length > counterSignature.Length) { RSACryptoServiceProvider rsa = (RSACryptoServiceProvider) x509.RSA; // we need to HACK around bad (PKCS#1 1.5) signatures made by Verisign Timestamp Service // and this means copying stuff into our own RSAManaged to get the required flexibility RSAManaged rsam = new RSAManaged (); rsam.ImportParameters (rsa.ExportParameters (false)); if (PKCS1.Verify_v15 (rsam, ha, p7hash, counterSignature, true)) { timestampChain.LoadCertificates (coll); return (timestampChain.Build (x509)); } } } } // no certificate can verify this signature! return false; }
public SubjectAltNameExtension(ASN1 asn1) : base(asn1) { }
private bool CheckSignature (string fileName) { filename = fileName; Open (filename); entry = GetSecurityEntry (); if (entry == null) { // no signature is present reason = 1; Close (); return false; } PKCS7.ContentInfo ci = new PKCS7.ContentInfo (entry); if (ci.ContentType != PKCS7.Oid.signedData) { Close (); return false; } PKCS7.SignedData sd = new PKCS7.SignedData (ci.Content); if (sd.ContentInfo.ContentType != spcIndirectDataContext) { Close (); return false; } coll = sd.Certificates; ASN1 spc = sd.ContentInfo.Content; signedHash = spc [0][1][1]; HashAlgorithm ha = null; switch (signedHash.Length) { case 16: ha = HashAlgorithm.Create ("MD5"); hash = GetHash (ha); break; case 20: ha = HashAlgorithm.Create ("SHA1"); hash = GetHash (ha); break; default: reason = 5; Close (); return false; } Close (); if (!signedHash.CompareValue (hash)) { reason = 2; } // messageDigest is a hash of spcIndirectDataContext (which includes the file hash) byte[] spcIDC = spc [0].Value; ha.Initialize (); // re-using hash instance byte[] messageDigest = ha.ComputeHash (spcIDC); bool sign = VerifySignature (sd, messageDigest, ha); return (sign && (reason == 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 (); }
public string GetNameInfo(X509NameType nameType, bool forIssuer) { switch (nameType) { case X509NameType.SimpleName: { if (this._cert == null) { throw new CryptographicException(X509Certificate2.empty_error); } ASN1 asn = (!forIssuer) ? this._cert.GetSubjectName() : this._cert.GetIssuerName(); ASN1 asn2 = this.Find(X509Certificate2.commonName, asn); if (asn2 != null) { return(this.GetValueAsString(asn2)); } if (asn.Count == 0) { return(string.Empty); } ASN1 asn3 = asn[asn.Count - 1]; if (asn3.Count == 0) { return(string.Empty); } return(this.GetValueAsString(asn3[0])); } case X509NameType.EmailName: { ASN1 asn4 = this.Find(X509Certificate2.email, (!forIssuer) ? this._cert.GetSubjectName() : this._cert.GetIssuerName()); if (asn4 != null) { return(this.GetValueAsString(asn4)); } return(string.Empty); } case X509NameType.UpnName: return(string.Empty); case X509NameType.DnsName: { ASN1 asn5 = this.Find(X509Certificate2.commonName, (!forIssuer) ? this._cert.GetSubjectName() : this._cert.GetIssuerName()); if (asn5 != null) { return(this.GetValueAsString(asn5)); } return(string.Empty); } case X509NameType.DnsFromAlternativeName: return(string.Empty); case X509NameType.UrlName: return(string.Empty); default: throw new ArgumentException("nameType"); } }
public X509SubjectKeyIdentifierExtension (PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical) { if (key == null) throw new ArgumentNullException ("key"); byte[] pkraw = key.EncodedKeyValue.RawData; // compute SKI switch (algorithm) { // hash of the public key, excluding Tag, Length and unused bits values case X509SubjectKeyIdentifierHashAlgorithm.Sha1: _subjectKeyIdentifier = SHA1.Create ().ComputeHash (pkraw); break; // 0100 bit pattern followed by the 60 last bit of the hash case X509SubjectKeyIdentifierHashAlgorithm.ShortSha1: byte[] hash = SHA1.Create ().ComputeHash (pkraw); _subjectKeyIdentifier = new byte [8]; Buffer.BlockCopy (hash, 12, _subjectKeyIdentifier, 0, 8); _subjectKeyIdentifier [0] = (byte) (0x40 | (_subjectKeyIdentifier [0] & 0x0F)); break; // hash of the public key, including Tag, Length and unused bits values case X509SubjectKeyIdentifierHashAlgorithm.CapiSha1: // CryptoAPI does that hash on the complete subjectPublicKeyInfo (unlike PKIX) // http://groups.google.ca/groups?selm=e7RqM%24plCHA.1488%40tkmsftngp02&oe=UTF-8&output=gplain ASN1 subjectPublicKeyInfo = new ASN1 (0x30); ASN1 algo = subjectPublicKeyInfo.Add (new ASN1 (0x30)); algo.Add (new ASN1 (CryptoConfig.EncodeOID (key.Oid.Value))); algo.Add (new ASN1 (key.EncodedParameters.RawData)); // add an extra byte for the unused bits (none) byte[] full = new byte [pkraw.Length + 1]; Buffer.BlockCopy (pkraw, 0, full, 1, pkraw.Length); subjectPublicKeyInfo.Add (new ASN1 (0x03, full)); _subjectKeyIdentifier = SHA1.Create ().ComputeHash (subjectPublicKeyInfo.GetBytes ()); break; default: throw new ArgumentException ("algorithm"); } _oid = new Oid (oid, friendlyName); base.Critical = critical; RawData = Encode (); }
/* * 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); #if MOONLIGHT RSA rsa = RSA.Create (); rsa.ImportParameters (param); #else 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); } #endif return rsa; }
internal byte[] Encode() { ASN1 ex = new ASN1(0x04, _subjectKeyIdentifier); return(ex.GetBytes()); }
public AuthorityKeyIdentifierExtension(ASN1 asn1) : base(asn1) { }
public void ASN1encode(EncodeBuffer buffer) { ASN1.bacapp_encode_device_obj_property_ref(buffer, this); }
public byte[] GetBytes() { return(ASN1.GetBytes()); }
public PrivateKeyUsagePeriodExtension(ASN1 asn1) : base(asn1) { }
public async Task <Tuple <bool, string> > VerifyHttpSignature(HttpContext context) { var signatureHeader = context.Request.Headers["Signature"].FirstOrDefault(); if (signatureHeader == null) { return(new Tuple <bool, string>(true, null)); } var parameters = signatureHeader.Replace("\\\"", "\n").Split(',').Select((a) => a.Split(new[] { '=' }, 2)).ToDictionary((a) => a[0], (a) => a[1].Trim('"').Replace("\n", "\\\"")); if (!parameters.ContainsKey("keyId") || !parameters.ContainsKey("algorithm") || !parameters.ContainsKey("signature")) { return(new Tuple <bool, string>(false, null)); } if (!parameters.ContainsKey("headers")) { parameters["headers"] = "date"; } var key = await _entityStore.GetEntity(parameters["keyId"], true); if (key == null) { return(new Tuple <bool, string>(false, null)); } var owner = await _entityStore.GetEntity((string)key.Data["owner"].First().Primitive, true); if (!owner.Data["publicKey"].Any((a) => (string)a.Primitive == key.Id)) { return(new Tuple <bool, string>(false, null)); } var stringKey = (string)key.Data["publicKeyPem"].First().Primitive; if (!stringKey.StartsWith("-----BEGIN PUBLIC KEY-----")) { return(new Tuple <bool, string>(false, null)); } var toDecode = stringKey.Trim().Remove(0, stringKey.IndexOf('\n')); toDecode = toDecode.Remove(toDecode.LastIndexOf('\n')).Replace("\n", ""); var signKey = ASN1.ToRSA(Convert.FromBase64String(toDecode)); var toSign = new StringBuilder(); foreach (var headerKey in parameters["headers"].Split(' ')) { if (headerKey == "(request-target)") { toSign.Append($"(request-target): {context.Request.Method.ToLower()} {context.Request.Path}{context.Request.QueryString}\n"); } else { toSign.Append($"{headerKey}: {string.Join(", ", context.Request.Headers[headerKey])}\n"); } } toSign.Remove(toSign.Length - 1, 1); var signature = Convert.FromBase64String(parameters["signature"]); switch (parameters["algorithm"]) { case "rsa-sha256": return(new Tuple <bool, string>(signKey.VerifyData(Encoding.UTF8.GetBytes(toSign.ToString()), signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1), owner.Id)); } return(new Tuple <bool, string>(false, owner.Id)); }
private void Parse(byte[] data) { try { decoder = new ASN1(data); if (decoder.Tag != 48) { throw new CryptographicException(encoding_error); } if (decoder[0].Tag != 48) { throw new CryptographicException(encoding_error); } ASN1 aSN = decoder[0]; int num = 0; ASN1 aSN2 = decoder[0][num]; version = 1; if (aSN2.Tag == 160 && aSN2.Count > 0) { version += aSN2[0].Value[0]; num++; } ASN1 aSN3 = decoder[0][num++]; if (aSN3.Tag != 2) { throw new CryptographicException(encoding_error); } serialnumber = aSN3.Value; Array.Reverse(serialnumber, 0, serialnumber.Length); num++; issuer = aSN.Element(num++, 48); m_issuername = X501.ToString(issuer); ASN1 aSN4 = aSN.Element(num++, 48); ASN1 time = aSN4[0]; m_from = ASN1Convert.ToDateTime(time); ASN1 time2 = aSN4[1]; m_until = ASN1Convert.ToDateTime(time2); subject = aSN.Element(num++, 48); m_subject = X501.ToString(subject); ASN1 aSN5 = aSN.Element(num++, 48); ASN1 aSN6 = aSN5.Element(0, 48); ASN1 asn = aSN6.Element(0, 6); m_keyalgo = ASN1Convert.ToOid(asn); ASN1 aSN7 = aSN6[1]; m_keyalgoparams = ((aSN6.Count <= 1) ? null : aSN7.GetBytes()); ASN1 aSN8 = aSN5.Element(1, 3); int num7 = aSN8.Length - 1; m_publickey = new byte[num7]; Buffer.BlockCopy(aSN8.Value, 1, m_publickey, 0, num7); byte[] value = decoder[2].Value; signature = new byte[value.Length - 1]; Buffer.BlockCopy(value, 1, signature, 0, signature.Length); aSN6 = decoder[1]; asn = aSN6.Element(0, 6); m_signaturealgo = ASN1Convert.ToOid(asn); aSN7 = aSN6[1]; if (aSN7 != null) { m_signaturealgoparams = aSN7.GetBytes(); } else { m_signaturealgoparams = null; } ASN1 aSN9 = aSN.Element(num, 129); if (aSN9 != null) { num++; issuerUniqueID = aSN9.Value; } ASN1 aSN10 = aSN.Element(num, 130); if (aSN10 != null) { num++; subjectUniqueID = aSN10.Value; } ASN1 aSN11 = aSN.Element(num, 163); if (aSN11 != null && aSN11.Count == 1) { extensions = new X509ExtensionCollection(aSN11[0]); } else { extensions = new X509ExtensionCollection(null); } m_encodedcert = (byte[])data.Clone(); } catch (Exception inner) { throw new CryptographicException(encoding_error, inner); IL_035f :; } }
internal AsnDecodeStatus Decode (byte[] extension) { if ((extension == null) || (extension.Length == 0)) return AsnDecodeStatus.BadAsn; if (extension [0] != 0x03) return AsnDecodeStatus.BadTag; if (extension.Length < 3) return AsnDecodeStatus.BadLength; if (extension.Length < 4) return AsnDecodeStatus.InformationNotAvailable; try { ASN1 ex = new ASN1 (extension); int kubits = 0; int i = 1; // byte zero has the number of unused bits (ASN1's BITSTRING) while (i < ex.Value.Length) kubits = (kubits << 8) + ex.Value [i++]; _keyUsages = GetValidFlags ((X509KeyUsageFlags)kubits); } catch { return AsnDecodeStatus.BadAsn; } return AsnDecodeStatus.Ok; }
public void Decode(byte[] encodedMessage) { PKCS7.ContentInfo ci = new PKCS7.ContentInfo(encodedMessage); if (ci.ContentType != PKCS7.Oid.signedData) { throw new Exception(""); } PKCS7.SignedData sd = new PKCS7.SignedData(ci.Content); SubjectIdentifierType type = SubjectIdentifierType.Unknown; object o = null; X509Certificate2 x509 = null; if (sd.SignerInfo.Certificate != null) { x509 = new X509Certificate2(sd.SignerInfo.Certificate.RawData); } else if ((sd.SignerInfo.IssuerName != null) && (sd.SignerInfo.SerialNumber != null)) { byte[] serial = sd.SignerInfo.SerialNumber; Array.Reverse(serial); // ??? type = SubjectIdentifierType.IssuerAndSerialNumber; X509IssuerSerial xis = new X509IssuerSerial(); xis.IssuerName = sd.SignerInfo.IssuerName; xis.SerialNumber = ToString(serial, true); o = xis; // TODO: move to a FindCertificate (issuer, serial, collection) foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) { if (x.IssuerName == sd.SignerInfo.IssuerName) { if (ToString(x.SerialNumber, true) == xis.SerialNumber) { x509 = new X509Certificate2(x.RawData); break; } } } } else if (sd.SignerInfo.SubjectKeyIdentifier != null) { string ski = ToString(sd.SignerInfo.SubjectKeyIdentifier, false); type = SubjectIdentifierType.SubjectKeyIdentifier; o = (object)ski; // TODO: move to a FindCertificate (ski, collection) foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) { if (ToString(GetKeyIdentifier(x), false) == ski) { x509 = new X509Certificate2(x.RawData); break; } } } SignerInfo si = new SignerInfo(sd.SignerInfo.HashName, x509, type, o, sd.SignerInfo.Version); // si.AuthenticatedAttributes // si.UnauthenticatedAttributes _info.Add(si); ASN1 content = sd.ContentInfo.Content; Oid oid = new Oid(sd.ContentInfo.ContentType); if (!_detached || _content == null) { if (content[0] == null) { throw new ArgumentException("ContentInfo has no content. Detached signature ?"); } _content = new ContentInfo(oid, content[0].Value); } foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) { _certs.Add(new X509Certificate2(x.RawData)); } _version = sd.Version; }
internal AsnDecodeStatus Decode (byte[] extension) { if ((extension == null) || (extension.Length == 0)) return AsnDecodeStatus.BadAsn; _ski = String.Empty; if (extension [0] != 0x04) return AsnDecodeStatus.BadTag; if (extension.Length == 2) return AsnDecodeStatus.InformationNotAvailable; if (extension.Length < 3) return AsnDecodeStatus.BadLength; try { ASN1 ex = new ASN1 (extension); _subjectKeyIdentifier = ex.Value; } catch { return AsnDecodeStatus.BadAsn; } return AsnDecodeStatus.Ok; }
protected override void Decode() { ASN1 aSN = new ASN1(extnValue.Value); if (aSN.Tag != 48) { throw new ArgumentException("Invalid KeyAttributesExtension extension"); } int num = 0; if (num < aSN.Count) { ASN1 aSN2 = aSN[num]; if (aSN2.Tag == 4) { num++; keyId = aSN2.Value; } } if (num < aSN.Count) { ASN1 aSN3 = aSN[num]; if (aSN3.Tag == 3) { num++; int num2 = 1; while (num2 < aSN3.Value.Length) { kubits = (kubits << 8) + aSN3.Value[num2++]; } } } if (num >= aSN.Count) { return; } ASN1 aSN4 = aSN[num]; if (aSN4.Tag != 48) { return; } int num4 = 0; if (num4 < aSN4.Count) { ASN1 aSN5 = aSN4[num4]; if (aSN5.Tag == 129) { num4++; notBefore = ASN1Convert.ToDateTime(aSN5); } } if (num4 < aSN4.Count) { ASN1 aSN6 = aSN4[num4]; if (aSN6.Tag == 130) { notAfter = ASN1Convert.ToDateTime(aSN6); } } }
// 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]); } } }
private RSA getClientCertRSA(RSA privKey) { RSAParameters rsaParams = new RSAParameters(); RSAParameters privateParams = privKey.ExportParameters(true); // for RSA m_publickey contains 2 ASN.1 integers // the modulus and the public exponent ASN1 pubkey = new ASN1 (this.Context.ClientSettings.Certificates[0].GetPublicKey()); ASN1 modulus = pubkey [0]; if ((modulus == null) || (modulus.Tag != 0x02)) { return null; } ASN1 exponent = pubkey [1]; if (exponent.Tag != 0x02) { return null; } rsaParams.Modulus = this.getUnsignedBigInteger(modulus.Value); rsaParams.Exponent = exponent.Value; // Set private key parameters rsaParams.D = privateParams.D; rsaParams.DP = privateParams.DP; rsaParams.DQ = privateParams.DQ; rsaParams.InverseQ = privateParams.InverseQ; rsaParams.P = privateParams.P; rsaParams.Q = privateParams.Q; // BUG: MS BCL 1.0 can't import a key which // isn't the same size as the one present in // the container. int keySize = (rsaParams.Modulus.Length << 3); RSAManaged rsa = new RSAManaged(keySize); rsa.ImportParameters (rsaParams); return (RSA)rsa; }
// 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; }
public byte[] GetBytes () { ASN1 sequence = new ASN1 (0x30); sequence.Add (new ASN1 (0x02, sn)); sequence.Add (ASN1Convert.FromDateTime (revocationDate)); if (extensions.Count > 0) sequence.Add (new ASN1 (extensions.GetBytes ())); return sequence.GetBytes (); }
public KeyAttributesExtension(ASN1 asn1) : base(asn1) { }
public ExtendedKeyUsageExtension (ASN1 asn1) : base (asn1) { }
// Indirectly (undocumented but) supported extensions internal string SubjectAltName (bool multiLine) { if (_raw.Length < 5) return "Information Not Available"; try { ASN1 ex = new ASN1 (_raw); StringBuilder sb = new StringBuilder (); for (int i=0; i < ex.Count; i++) { ASN1 el = ex [i]; string type = null; string name = null; switch (el.Tag) { case 0x81: type = "RFC822 Name="; name = Encoding.ASCII.GetString (el.Value); break; case 0x82: type = "DNS Name="; name = Encoding.ASCII.GetString (el.Value); break; default: type = String.Format ("Unknown ({0})=", el.Tag); name = CryptoConvert.ToHex (el.Value); break; } sb.Append (type); sb.Append (name); if (multiLine) { sb.Append (Environment.NewLine); } else if (i < ex.Count - 1) { sb.Append (", "); } } return sb.ToString (); } catch { return String.Empty; } }
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); } } } } }
// 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; }
private bool CheckSignature() { if (filename != null) { Open(filename); } else { Open(rawdata); } entry = GetSecurityEntry(); if (entry == null) { // no signature is present reason = 1; Close(); return(false); } PKCS7.ContentInfo ci = new PKCS7.ContentInfo(entry); if (ci.ContentType != PKCS7.Oid.signedData) { Close(); return(false); } PKCS7.SignedData sd = new PKCS7.SignedData(ci.Content); if (sd.ContentInfo.ContentType != spcIndirectDataContext) { Close(); return(false); } coll = sd.Certificates; ASN1 spc = sd.ContentInfo.Content; signedHash = spc [0][1][1]; HashAlgorithm ha = null; switch (signedHash.Length) { case 16: ha = MD5.Create(); hash = GetHash(ha); break; case 20: ha = SHA1.Create(); hash = GetHash(ha); break; case 32: ha = SHA256.Create(); hash = GetHash(ha); break; case 48: ha = SHA384.Create(); hash = GetHash(ha); break; case 64: ha = SHA512.Create(); hash = GetHash(ha); break; default: reason = 5; Close(); return(false); } Close(); if (!signedHash.CompareValue(hash)) { reason = 2; } // messageDigest is a hash of spcIndirectDataContext (which includes the file hash) byte[] spcIDC = spc [0].Value; ha.Initialize(); // re-using hash instance byte[] messageDigest = ha.ComputeHash(spcIDC); bool sign = VerifySignature(sd, messageDigest, ha); return(sign && (reason == 0)); }
private void Parse (byte[] crl) { string e = "Input data cannot be coded as a valid CRL."; try { // CertificateList ::= SEQUENCE { ASN1 encodedCRL = new ASN1 (encoded); if ((encodedCRL.Tag != 0x30) || (encodedCRL.Count != 3)) throw new CryptographicException (e); // CertificateList / TBSCertList, ASN1 toBeSigned = encodedCRL [0]; if ((toBeSigned.Tag != 0x30) || (toBeSigned.Count < 3)) throw new CryptographicException (e); int n = 0; // CertificateList / TBSCertList / Version OPTIONAL, -- if present, MUST be v2 if (toBeSigned [n].Tag == 0x02) { version = (byte) (toBeSigned [n++].Value [0] + 1); } else version = 1; // DEFAULT // CertificateList / TBSCertList / AlgorithmIdentifier, signatureOID = ASN1Convert.ToOid (toBeSigned [n++][0]); // CertificateList / TBSCertList / Name, issuer = X501.ToString (toBeSigned [n++]); // CertificateList / TBSCertList / Time, thisUpdate = ASN1Convert.ToDateTime (toBeSigned [n++]); // CertificateList / TBSCertList / Time OPTIONAL, ASN1 next = toBeSigned [n++]; if ((next.Tag == 0x17) || (next.Tag == 0x18)) { nextUpdate = ASN1Convert.ToDateTime (next); next = toBeSigned [n++]; } // CertificateList / TBSCertList / revokedCertificates SEQUENCE OF SEQUENCE { entries = new ArrayList (); // this is OPTIONAL so it may not be present if no entries exists if ((next != null) && (next.Tag == 0x30)) { ASN1 revokedCertificates = next; for (int i=0; i < revokedCertificates.Count; i++) { entries.Add (new X509CrlEntry (revokedCertificates [i])); } } else { n--; } // CertificateList / TBSCertList / crlExtensions [0] Extensions OPTIONAL } ASN1 extns = toBeSigned [n]; if ((extns != null) && (extns.Tag == 0xA0) && (extns.Count == 1)) extensions = new X509ExtensionCollection (extns [0]); else extensions = new X509ExtensionCollection (null); // result in a read only object // CertificateList / AlgorithmIdentifier string signatureAlgorithm = ASN1Convert.ToOid (encodedCRL [1][0]); if (signatureOID != signatureAlgorithm) throw new CryptographicException (e + " [Non-matching signature algorithms in CRL]"); // CertificateList / BIT STRING byte[] bitstring = encodedCRL [2].Value; // first byte contains unused bits in first byte signature = new byte [bitstring.Length - 1]; Buffer.BlockCopy (bitstring, 1, signature, 0, signature.Length); } catch { throw new CryptographicException (e); } }
//private bool VerifySignature (ASN1 cs, byte[] calculatedMessageDigest, string hashName) private bool VerifySignature(PKCS7.SignedData sd, byte[] calculatedMessageDigest, HashAlgorithm ha) { string contentType = null; ASN1 messageDigest = null; // string spcStatementType = null; // string spcSpOpusInfo = null; for (int i = 0; i < sd.SignerInfo.AuthenticatedAttributes.Count; i++) { ASN1 attr = (ASN1)sd.SignerInfo.AuthenticatedAttributes [i]; string oid = ASN1Convert.ToOid(attr[0]); switch (oid) { case "1.2.840.113549.1.9.3": // contentType contentType = ASN1Convert.ToOid(attr[1][0]); break; case "1.2.840.113549.1.9.4": // messageDigest messageDigest = attr[1][0]; break; case "1.3.6.1.4.1.311.2.1.11": // spcStatementType (Microsoft code signing) // possible values // - individualCodeSigning (1 3 6 1 4 1 311 2 1 21) // - commercialCodeSigning (1 3 6 1 4 1 311 2 1 22) // spcStatementType = ASN1Convert.ToOid (attr[1][0][0]); break; case "1.3.6.1.4.1.311.2.1.12": // spcSpOpusInfo (Microsoft code signing) /* try { * spcSpOpusInfo = System.Text.Encoding.UTF8.GetString (attr[1][0][0][0].Value); * } * catch (NullReferenceException) { * spcSpOpusInfo = null; * }*/ break; default: break; } } if (contentType != spcIndirectDataContext) { return(false); } // verify message digest if (messageDigest == null) { return(false); } if (!messageDigest.CompareValue(calculatedMessageDigest)) { return(false); } // verify signature string hashOID = CryptoConfig.MapNameToOID(ha.ToString()); // change to SET OF (not [0]) as per PKCS #7 1.5 ASN1 aa = new ASN1(0x31); foreach (ASN1 a in sd.SignerInfo.AuthenticatedAttributes) { aa.Add(a); } ha.Initialize(); byte[] p7hash = ha.ComputeHash(aa.GetBytes()); byte[] signature = sd.SignerInfo.Signature; // we need to find the specified certificate string issuer = sd.SignerInfo.IssuerName; byte[] serial = sd.SignerInfo.SerialNumber; foreach (X509Certificate x509 in coll) { if (CompareIssuerSerial(issuer, serial, x509)) { // don't verify is key size don't match if (x509.PublicKey.Length > (signature.Length >> 3)) { // return the signing certificate even if the signature isn't correct // (required behaviour for 2.0 support) signingCertificate = x509; RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)x509.RSA; if (rsa.VerifyHash(p7hash, hashOID, signature)) { signerChain.LoadCertificates(coll); trustedRoot = signerChain.Build(x509); break; } } } } // timestamp signature is optional if (sd.SignerInfo.UnauthenticatedAttributes.Count == 0) { trustedTimestampRoot = true; } else { for (int i = 0; i < sd.SignerInfo.UnauthenticatedAttributes.Count; i++) { ASN1 attr = (ASN1)sd.SignerInfo.UnauthenticatedAttributes[i]; string oid = ASN1Convert.ToOid(attr[0]); switch (oid) { case PKCS7.Oid.countersignature: // SEQUENCE { // OBJECT IDENTIFIER // countersignature (1 2 840 113549 1 9 6) // SET { PKCS7.SignerInfo cs = new PKCS7.SignerInfo(attr[1]); trustedTimestampRoot = VerifyCounterSignature(cs, signature); break; default: // we don't support other unauthenticated attributes break; } } } return(trustedRoot && trustedTimestampRoot); }
private bool VerifyCounterSignature(PKCS7.SignerInfo cs, byte[] signature) { // SEQUENCE { // INTEGER 1 if (cs.Version > 1) { return(false); } // SEQUENCE { // SEQUENCE { string contentType = null; ASN1 messageDigest = null; for (int i = 0; i < cs.AuthenticatedAttributes.Count; i++) { // SEQUENCE { // OBJECT IDENTIFIER ASN1 attr = (ASN1)cs.AuthenticatedAttributes [i]; string oid = ASN1Convert.ToOid(attr[0]); switch (oid) { case "1.2.840.113549.1.9.3": // contentType contentType = ASN1Convert.ToOid(attr[1][0]); break; case "1.2.840.113549.1.9.4": // messageDigest messageDigest = attr[1][0]; break; case "1.2.840.113549.1.9.5": // SEQUENCE { // OBJECT IDENTIFIER // signingTime (1 2 840 113549 1 9 5) // SET { // UTCTime '030124013651Z' // } // } timestamp = ASN1Convert.ToDateTime(attr[1][0]); break; default: break; } } if (contentType != PKCS7.Oid.data) { return(false); } // verify message digest if (messageDigest == null) { return(false); } // TODO: must be read from the ASN.1 structure string hashName = null; switch (messageDigest.Length) { case 16: hashName = "MD5"; break; case 20: hashName = "SHA1"; break; case 32: hashName = "SHA256"; break; case 48: hashName = "SHA384"; break; case 64: hashName = "SHA512"; break; } HashAlgorithm ha = HashAlgorithm.Create(hashName); if (!messageDigest.CompareValue(ha.ComputeHash(signature))) { return(false); } // verify signature byte[] counterSignature = cs.Signature; // change to SET OF (not [0]) as per PKCS #7 1.5 ASN1 aa = new ASN1(0x31); foreach (ASN1 a in cs.AuthenticatedAttributes) { aa.Add(a); } byte[] p7hash = ha.ComputeHash(aa.GetBytes()); // we need to try all certificates string issuer = cs.IssuerName; byte[] serial = cs.SerialNumber; foreach (X509Certificate x509 in coll) { if (CompareIssuerSerial(issuer, serial, x509)) { if (x509.PublicKey.Length > counterSignature.Length) { RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)x509.RSA; // we need to HACK around bad (PKCS#1 1.5) signatures made by Verisign Timestamp Service // and this means copying stuff into our own RSAManaged to get the required flexibility RSAManaged rsam = new RSAManaged(); rsam.ImportParameters(rsa.ExportParameters(false)); if (PKCS1.Verify_v15(rsam, ha, p7hash, counterSignature, true)) { timestampChain.LoadCertificates(coll); return(timestampChain.Build(x509)); } } } } // no certificate can verify this signature! return(false); }
private void Parse(byte[] crl) { string message = "Input data cannot be coded as a valid CRL."; try { ASN1 asn = new ASN1(this.encoded); if ((asn.Tag != 0x30) || (asn.Count != 3)) { throw new CryptographicException(message); } ASN1 asn2 = asn[0]; if ((asn2.Tag != 0x30) || (asn2.Count < 3)) { throw new CryptographicException(message); } int num = 0; if (asn2[num].Tag == 2) { this.version = (byte)(asn2[num++].Value[0] + 1); } else { this.version = 1; } this.signatureOID = ASN1Convert.ToOid(asn2[num++][0]); this.issuer = X501.ToString(asn2[num++]); this.thisUpdate = ASN1Convert.ToDateTime(asn2[num++]); ASN1 time = asn2[num++]; if ((time.Tag == 0x17) || (time.Tag == 0x18)) { this.nextUpdate = ASN1Convert.ToDateTime(time); time = asn2[num++]; } this.entries = new ArrayList(); if ((time != null) && (time.Tag == 0x30)) { ASN1 asn4 = time; for (int i = 0; i < asn4.Count; i++) { this.entries.Add(new X509CrlEntry(asn4[i])); } } else { num--; } ASN1 asn5 = asn2[num]; if (((asn5 != null) && (asn5.Tag == 160)) && (asn5.Count == 1)) { this.extensions = new X509ExtensionCollection(asn5[0]); } else { this.extensions = new X509ExtensionCollection(null); } string str2 = ASN1Convert.ToOid(asn[1][0]); if (this.signatureOID != str2) { throw new CryptographicException(message + " [Non-matching signature algorithms in CRL]"); } byte[] src = asn[2].Value; this.signature = new byte[src.Length - 1]; Buffer.BlockCopy(src, 1, this.signature, 0, this.signature.Length); } catch { throw new CryptographicException(message); } }
//private bool VerifySignature (ASN1 cs, byte[] calculatedMessageDigest, string hashName) private bool VerifySignature (PKCS7.SignedData sd, byte[] calculatedMessageDigest, HashAlgorithm ha) { string contentType = null; ASN1 messageDigest = null; // string spcStatementType = null; // string spcSpOpusInfo = null; for (int i=0; i < sd.SignerInfo.AuthenticatedAttributes.Count; i++) { ASN1 attr = (ASN1) sd.SignerInfo.AuthenticatedAttributes [i]; string oid = ASN1Convert.ToOid (attr[0]); switch (oid) { case "1.2.840.113549.1.9.3": // contentType contentType = ASN1Convert.ToOid (attr[1][0]); break; case "1.2.840.113549.1.9.4": // messageDigest messageDigest = attr[1][0]; break; case "1.3.6.1.4.1.311.2.1.11": // spcStatementType (Microsoft code signing) // possible values // - individualCodeSigning (1 3 6 1 4 1 311 2 1 21) // - commercialCodeSigning (1 3 6 1 4 1 311 2 1 22) // spcStatementType = ASN1Convert.ToOid (attr[1][0][0]); break; case "1.3.6.1.4.1.311.2.1.12": // spcSpOpusInfo (Microsoft code signing) /* try { spcSpOpusInfo = System.Text.Encoding.UTF8.GetString (attr[1][0][0][0].Value); } catch (NullReferenceException) { spcSpOpusInfo = null; }*/ break; default: break; } } if (contentType != spcIndirectDataContext) return false; // verify message digest if (messageDigest == null) return false; if (!messageDigest.CompareValue (calculatedMessageDigest)) return false; // verify signature string hashOID = CryptoConfig.MapNameToOID (ha.ToString ()); // change to SET OF (not [0]) as per PKCS #7 1.5 ASN1 aa = new ASN1 (0x31); foreach (ASN1 a in sd.SignerInfo.AuthenticatedAttributes) aa.Add (a); ha.Initialize (); byte[] p7hash = ha.ComputeHash (aa.GetBytes ()); byte[] signature = sd.SignerInfo.Signature; // we need to find the specified certificate string issuer = sd.SignerInfo.IssuerName; byte[] serial = sd.SignerInfo.SerialNumber; foreach (X509Certificate x509 in coll) { if (CompareIssuerSerial (issuer, serial, x509)) { // don't verify is key size don't match if (x509.PublicKey.Length > (signature.Length >> 3)) { // return the signing certificate even if the signature isn't correct // (required behaviour for 2.0 support) signingCertificate = x509; RSACryptoServiceProvider rsa = (RSACryptoServiceProvider) x509.RSA; if (rsa.VerifyHash (p7hash, hashOID, signature)) { signerChain.LoadCertificates (coll); trustedRoot = signerChain.Build (x509); break; } } } } // timestamp signature is optional if (sd.SignerInfo.UnauthenticatedAttributes.Count == 0) { trustedTimestampRoot = true; } else { for (int i = 0; i < sd.SignerInfo.UnauthenticatedAttributes.Count; i++) { ASN1 attr = (ASN1) sd.SignerInfo.UnauthenticatedAttributes[i]; string oid = ASN1Convert.ToOid (attr[0]); switch (oid) { case PKCS7.Oid.countersignature: // SEQUENCE { // OBJECT IDENTIFIER // countersignature (1 2 840 113549 1 9 6) // SET { PKCS7.SignerInfo cs = new PKCS7.SignerInfo (attr[1]); trustedTimestampRoot = VerifyCounterSignature (cs, signature); break; default: // we don't support other unauthenticated attributes break; } } } return (trustedRoot && trustedTimestampRoot); }
public SubjectKeyIdentifierExtension(ASN1 asn1) : base(asn1) { }
private void Reset () { filename = null; entry = null; hash = null; signedHash = null; signingCertificate = null; reason = -1; trustedRoot = false; trustedTimestampRoot = false; signerChain.Reset (); timestampChain.Reset (); timestamp = DateTime.MinValue; }
// 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); } }
internal byte[] Encode () { ASN1 ex = null; int kubits = (int)_keyUsages; byte empty = 0; if (kubits == 0) { ex = new ASN1 (0x03, new byte[] { empty }); } else { // count empty bits (applicable to first byte only) int ku = ((kubits < Byte.MaxValue) ? kubits : (kubits >> 8)); while (((ku & 0x01) == 0x00) && (empty < 8)) { empty++; ku >>= 1; } if (kubits <= Byte.MaxValue) { ex = new ASN1 (0x03, new byte[] { empty, (byte)kubits }); } else { ex = new ASN1 (0x03, new byte[] { empty, (byte)kubits, (byte)(kubits >> 8) }); } } return ex.GetBytes (); }
public string GetNameInfo(X509NameType nameType, bool forIssuer) { switch (nameType) { case X509NameType.SimpleName: if (_cert == null) { throw new CryptographicException(empty_error); } // return CN= or, if missing, the first part of the DN ASN1 sn = forIssuer ? _cert.GetIssuerName() : _cert.GetSubjectName(); ASN1 dn = Find(commonName, sn); if (dn != null) { return(GetValueAsString(dn)); } if (sn.Count == 0) { return(String.Empty); } ASN1 last_entry = sn [sn.Count - 1]; if (last_entry.Count == 0) { return(String.Empty); } return(GetValueAsString(last_entry [0])); case X509NameType.EmailName: // return the E= part of the DN (if present) ASN1 e = Find(email, forIssuer ? _cert.GetIssuerName() : _cert.GetSubjectName()); if (e != null) { return(GetValueAsString(e)); } return(String.Empty); case X509NameType.UpnName: // FIXME - must find/create test case return(String.Empty); case X509NameType.DnsName: // return the CN= part of the DN (if present) ASN1 cn = Find(commonName, forIssuer ? _cert.GetIssuerName() : _cert.GetSubjectName()); if (cn != null) { return(GetValueAsString(cn)); } return(String.Empty); case X509NameType.DnsFromAlternativeName: // FIXME - must find/create test case return(String.Empty); case X509NameType.UrlName: // FIXME - must find/create test case return(String.Empty); default: throw new ArgumentException("nameType"); } }
internal byte[] Encode () { ASN1 ex = new ASN1 (0x04, _subjectKeyIdentifier); return ex.GetBytes (); }
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(", "); } } }
protected override void Read (TlsBuffer incoming) { var length = incoming.ReadByte (); for (int i = 0; i < length; i++) Parameters.CertificateTypes.Add ((ClientCertificateType)incoming.ReadByte ()); if (Protocol == TlsProtocolCode.Tls12) { var length2 = incoming.ReadInt16 (); if ((length2 % 2) != 0) throw new TlsException (AlertDescription.IlegalParameter); var signatureTypes = new SignatureAndHashAlgorithm [length2 >> 1]; for (int i = 0; i < signatureTypes.Length; i++) Parameters.SignatureParameters.SignatureAndHashAlgorithms.Add (new SignatureAndHashAlgorithm (incoming)); } var length3 = incoming.ReadInt16 (); if (incoming.Remaining != length3) throw new TlsException (AlertDescription.DecodeError); /* * Read requested certificate authorities (Distinguised Names) * * Name ::= SEQUENCE OF RelativeDistinguishedName * * RelativeDistinguishedName ::= SET OF AttributeValueAssertion * * AttributeValueAssertion ::= SEQUENCE { * attributeType OBJECT IDENTIFIER * attributeValue ANY * } * */ while (incoming.Remaining > 0) { var rdn = new ASN1 (incoming.ReadBytes (incoming.ReadInt16 ())); Parameters.CertificateAuthorities.Add (X501.ToString (rdn)); } }
public CRLDistributionPointsExtension(ASN1 asn1) : base(asn1) { }
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 (); }
internal bool VerifySignature (DSA dsa) { if (signatureOID != "1.2.840.10040.4.3") throw new CryptographicException ("Unsupported hash algorithm: " + signatureOID); DSASignatureDeformatter v = new DSASignatureDeformatter (dsa); // only SHA-1 is supported string hashName = "SHA1"; v.SetHashAlgorithm (hashName); ASN1 sign = new ASN1 (signature); if ((sign == null) || (sign.Count != 2)) return false; // parts may be less than 20 bytes (i.e. first bytes were 0x00) byte[] part1 = sign [0].Value; byte[] part2 = sign [1].Value; byte[] sig = new byte [40]; Buffer.BlockCopy (part1, 0, sig, (20 - part1.Length), part1.Length); Buffer.BlockCopy (part2, 0, sig, (40 - part2.Length), part2.Length); return v.VerifySignature (GetHash (hashName), sig); }
/* * 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 (); }
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("ST="); // Changed to be RFC2253 Compliant 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(", "); } }
// 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; }
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(); }
// 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); } }
private void ReadEffectiveWeeklySchedule() { Schedule.BeginUpdate(); Schedule.Nodes.Clear(); byte[] InOutBuffer = null; try { if (comm.RawEncodedDecodedPropertyConfirmedRequest(adr, schedule_id, BacnetPropertyIds.PROP_WEEKLY_SCHEDULE, BacnetConfirmedServices.SERVICE_CONFIRMED_READ_PROPERTY, ref InOutBuffer)) { int offset = 0; byte tag_number; uint len_value_type; // Tag 3 offset += ASN1.decode_tag_number(InOutBuffer, offset, out tag_number); if (tag_number != 3) { return; } for (int i = 1; i < 8; i++) { TreeNode tday = null; tday = new TreeNode("[" + (i - 1).ToString() + "] : " + System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat.DayNames[i % 7], 0, 0); Schedule.Nodes.Add(tday); // Tag 0 offset += ASN1.decode_tag_number(InOutBuffer, offset, out tag_number); while (!ASN1.IS_CLOSING_TAG(InOutBuffer[offset])) { BacnetValue value; String s; // Time offset += ASN1.decode_tag_number_and_value(InOutBuffer, offset, out tag_number, out len_value_type); offset += ASN1.bacapp_decode_data(InOutBuffer, offset, InOutBuffer.Length, (BacnetApplicationTags)tag_number, len_value_type, out value); DateTime dt = (DateTime)value.Value; // Value offset += ASN1.decode_tag_number_and_value(InOutBuffer, offset, out tag_number, out len_value_type); offset += ASN1.bacapp_decode_data(InOutBuffer, offset, InOutBuffer.Length, (BacnetApplicationTags)tag_number, len_value_type, out value); if (value.Tag != BacnetApplicationTags.BACNET_APPLICATION_TAG_NULL) { s = dt.ToString("T") + " = " + Property.SerializeValue(value, value.Tag); // Second value is the ... value (Bool, Int, Uint, Float, double or null) ScheduleType = value.Tag; // all type must be the same for a valid schedule (maybe, not sure !), so remember it } else { s = dt.ToString("T") + " = null"; } tday.Nodes.Add(new TreeNode(s, 1, 1)); } offset++; } offset += ASN1.decode_tag_number(InOutBuffer, offset, out tag_number); if (tag_number != 3) { Schedule.Nodes.Clear(); } } } catch { } finally { Schedule.EndUpdate(); Schedule.Sort(); // Time entries are not necesserary sorted, so do it (that's also why days are assign to [0], .. [6]) Schedule.ExpandAll(); Schedule.LabelEdit = true; } }
internal bool VerifySignature (DSA dsa) { if (signatureOID != "1.2.840.10040.4.3") throw new CryptographicException ("Unsupported hash algorithm: " + signatureOID); DSASignatureDeformatter v = new DSASignatureDeformatter (dsa); // only SHA-1 is supported v.SetHashAlgorithm ("SHA1"); ASN1 sign = new ASN1 (signature); if ((sign == null) || (sign.Count != 2)) return false; // parts may be less than 20 bytes (i.e. first bytes were 0x00) byte[] part1 = sign [0].Value; byte[] part2 = sign [1].Value; byte[] sig = new byte [40]; // parts may be less than 20 bytes (i.e. first bytes were 0x00) // parts may be more than 20 bytes (i.e. first byte > 0x80, negative) int s1 = System.Math.Max (0, part1.Length - 20); int e1 = System.Math.Max (0, 20 - part1.Length); Buffer.BlockCopy (part1, s1, sig, e1, part1.Length - s1); int s2 = System.Math.Max (0, part2.Length - 20); int e2 = System.Math.Max (20, 40 - part2.Length); Buffer.BlockCopy (part2, s2, sig, e2, part2.Length - s2); return v.VerifySignature (Hash, sig); }