// 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; }
// 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]); } } }
public EncryptedData(ASN1 asn1) : this() { if ((asn1.Tag != 0x30) || (asn1.Count < 2)) { throw new ArgumentException("Invalid EncryptedData"); } if (asn1 [0].Tag != 0x02) { throw new ArgumentException("Invalid version"); } _version = asn1 [0].Value [0]; ASN1 encryptedContentInfo = asn1 [1]; if (encryptedContentInfo.Tag != 0x30) { throw new ArgumentException("missing EncryptedContentInfo"); } ASN1 contentType = encryptedContentInfo [0]; if (contentType.Tag != 0x06) { throw new ArgumentException("missing EncryptedContentInfo.ContentType"); } _content = new ContentInfo(ASN1Convert.ToOid(contentType)); ASN1 contentEncryptionAlgorithm = encryptedContentInfo [1]; if (contentEncryptionAlgorithm.Tag != 0x30) { throw new ArgumentException("missing EncryptedContentInfo.ContentEncryptionAlgorithmIdentifier"); } _encryptionAlgorithm = new ContentInfo(ASN1Convert.ToOid(contentEncryptionAlgorithm [0])); _encryptionAlgorithm.Content = contentEncryptionAlgorithm [1]; ASN1 encryptedContent = encryptedContentInfo [2]; if (encryptedContent.Tag != 0x80) { throw new ArgumentException("missing EncryptedContentInfo.EncryptedContent"); } _encrypted = encryptedContent.Value; }
public ContentInfo(ASN1 asn1) { // SEQUENCE with 1 or 2 elements if ((asn1.Tag != 0x30) || ((asn1.Count < 1) && (asn1.Count > 2))) { throw new ArgumentException("Invalid ASN1"); } if (asn1[0].Tag != 0x06) { throw new ArgumentException("Invalid contentType"); } contentType = ASN1Convert.ToOid(asn1[0]); if (asn1.Count > 1) { if (asn1[1].Tag != 0xA0) { throw new ArgumentException("Invalid content"); } content = asn1[1]; } }
public RecipientInfo(ASN1 data) { if (data.Tag != 0x30) { throw new ArgumentException("Invalid RecipientInfo"); } ASN1 version = data [0]; if (version.Tag != 0x02) { throw new ArgumentException("missing Version"); } _version = version.Value [0]; // issuerAndSerialNumber IssuerAndSerialNumber ASN1 subjectIdentifierType = data [1]; if ((subjectIdentifierType.Tag == 0x80) && (_version == 3)) { _ski = subjectIdentifierType.Value; } else { _issuer = X501.ToString(subjectIdentifierType [0]); _serial = subjectIdentifierType [1].Value; } ASN1 keyEncryptionAlgorithm = data [2]; _oid = ASN1Convert.ToOid(keyEncryptionAlgorithm [0]); ASN1 encryptedKey = data [3]; _key = encryptedKey.Value; }
// TODO: INCOMPLETE public SignerInfo(ASN1 asn1) : this() { if ((asn1[0].Tag != 0x30) || (asn1[0].Count < 5)) { throw new ArgumentException("Invalid SignedData"); } // version Version if (asn1[0][0].Tag != 0x02) { throw new ArgumentException("Invalid version"); } version = asn1[0][0].Value[0]; // issuerAndSerialNumber IssuerAndSerialNumber ASN1 subjectIdentifierType = asn1 [0][1]; if ((subjectIdentifierType.Tag == 0x80) && (version == 3)) { ski = subjectIdentifierType.Value; } else { issuer = X501.ToString(subjectIdentifierType [0]); serial = subjectIdentifierType [1].Value; } // digestAlgorithm DigestAlgorithmIdentifier ASN1 digestAlgorithm = asn1 [0][2]; hashAlgorithm = ASN1Convert.ToOid(digestAlgorithm [0]); // authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL int n = 3; ASN1 authAttributes = asn1 [0][n]; if (authAttributes.Tag == 0xA0) { n++; for (int i = 0; i < authAttributes.Count; i++) { authenticatedAttributes.Add(authAttributes [i]); } } // digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier n++; // ASN1 digestEncryptionAlgorithm = asn1 [0][n++]; // string digestEncryptionAlgorithmOid = ASN1Convert.ToOid (digestEncryptionAlgorithm [0]); // encryptedDigest EncryptedDigest ASN1 encryptedDigest = asn1 [0][n++]; if (encryptedDigest.Tag == 0x04) { signature = encryptedDigest.Value; } // unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL ASN1 unauthAttributes = asn1 [0][n]; if ((unauthAttributes != null) && (unauthAttributes.Tag == 0xA1)) { for (int i = 0; i < unauthAttributes.Count; i++) { unauthenticatedAttributes.Add(unauthAttributes [i]); } } }
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(", "); } } }
// 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); } }