/* */ internal override void Encode( DerOutputStream derOut) { if (derOut is Asn1OutputStream || derOut is BerOutputStream) { derOut.WriteByte(Asn1Tags.Sequence | Asn1Tags.Constructed); derOut.WriteByte(0x80); foreach (Asn1Encodable o in this) { derOut.WriteObject(o); } derOut.WriteByte(0x00); derOut.WriteByte(0x00); } else { base.Encode(derOut); } }
public static void Save(this Pkcs12Store store, Stream stream, string encryptionPassword, string integrityPassword, SecureRandom random) { const int saltSize = 20; const int minIterations = 1024; if (stream == null) { throw new ArgumentNullException("stream"); } //if (null != encryptionPassword && encryptionPassword == integrityPassword) //{ // store.Save(stream, encryptionPassword.ToArray(), random); // return; //} if (random == null) { throw new ArgumentNullException("random"); } var T = store.GetType(); Func <AsymmetricKeyParameter, SubjectKeyIdentifier> CreateSubjectKeyID = (pubKey_) => { var method = T.GetMethod("CreateSubjectKeyID", BindingFlags.NonPublic | BindingFlags.Static); return((SubjectKeyIdentifier)method.Invoke(store, new object[] { pubKey_ })); }; Func <DerObjectIdentifier> keyAlgorithm = () => { var property = T.GetField("keyAlgorithm", BindingFlags.NonPublic | BindingFlags.Instance); return((DerObjectIdentifier)property.GetValue(store)); }; Func <DerObjectIdentifier> certAlgorithm = () => { var property = T.GetField("certAlgorithm", BindingFlags.NonPublic | BindingFlags.Instance); return((DerObjectIdentifier)property.GetValue(store)); }; // // handle the key // Asn1EncodableVector keyS = new Asn1EncodableVector(); var keys = store.Aliases.OfType <string>().ToDictionary(alias => alias, store.GetKey); foreach (string name in store.Aliases.OfType <string>()) { byte[] kSalt = new byte[saltSize]; random.NextBytes(kSalt); AsymmetricKeyEntry privKey = keys[name]; Asn1Encodable kInfo = null; if (!string.IsNullOrEmpty(encryptionPassword)) { kInfo = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(keyAlgorithm(), encryptionPassword.ToArray(), kSalt, minIterations, privKey.Key); } else { kInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privKey.Key); } Asn1EncodableVector kName = new Asn1EncodableVector(); foreach (string oid in privKey.BagAttributeKeys) { Asn1Encodable entry = privKey[oid]; // NB: Ignore any existing FriendlyName if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id)) { continue; } kName.Add(new DerSequence(new DerObjectIdentifier(oid), new DerSet(entry))); } // // make sure we are using the local alias on store // // NB: We always set the FriendlyName based on 'name' //if (privKey[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] == null) { kName.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(name)))); } // // make sure we have a local key-id // if (privKey[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null) { X509CertificateEntry ct = store.GetCertificate(name); AsymmetricKeyParameter pubKey = ct.Certificate.GetPublicKey(); SubjectKeyIdentifier subjectKeyID = CreateSubjectKeyID(pubKey); kName.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID, new DerSet(subjectKeyID))); } SafeBag kBag = null; if (!string.IsNullOrEmpty(encryptionPassword)) { kBag = new SafeBag(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag, kInfo.ToAsn1Object(), new DerSet(kName)); } else { kBag = new SafeBag(PkcsObjectIdentifiers.KeyBag, kInfo.ToAsn1Object(), new DerSet(kName)); } keyS.Add(kBag); } byte[] derEncodedBytes = new DerSequence(keyS).GetDerEncoded(); BerOctetString keyString = new BerOctetString(derEncodedBytes); // // certificate processing // byte[] cSalt = new byte[saltSize]; random.NextBytes(cSalt); Asn1EncodableVector certSeq = new Asn1EncodableVector(); Pkcs12PbeParams cParams = new Pkcs12PbeParams(cSalt, minIterations); AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(certAlgorithm(), cParams.ToAsn1Object()); ISet doneCerts = new HashSet(); foreach (string name in keys.Keys) { X509CertificateEntry certEntry = store.GetCertificate(name); CertBag cBag = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(certEntry.Certificate.GetEncoded())); Asn1EncodableVector fName = new Asn1EncodableVector(); foreach (string oid in certEntry.BagAttributeKeys) { Asn1Encodable entry = certEntry[oid]; // NB: Ignore any existing FriendlyName if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id)) { continue; } fName.Add(new DerSequence(new DerObjectIdentifier(oid), new DerSet(entry))); } // // make sure we are using the local alias on store // // NB: We always set the FriendlyName based on 'name' //if (certEntry[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] == null) { fName.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(name)))); } // // make sure we have a local key-id // if (certEntry[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null) { AsymmetricKeyParameter pubKey = certEntry.Certificate.GetPublicKey(); SubjectKeyIdentifier subjectKeyID = CreateSubjectKeyID(pubKey); fName.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID, new DerSet(subjectKeyID))); } SafeBag sBag = new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName)); certSeq.Add(sBag); doneCerts.Add(certEntry.Certificate); } var certs = store.Aliases.OfType <string>().Select(store.GetCertificate); foreach (var cert in certs) { //X509CertificateEntry cert = (X509CertificateEntry)certs[certId]; //if (keys[certId] != null) // continue; if (doneCerts.Contains(cert.Certificate)) { continue; } CertBag cBag = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(cert.Certificate.GetEncoded())); Asn1EncodableVector fName = new Asn1EncodableVector(); foreach (string oid in cert.BagAttributeKeys) { // a certificate not immediately linked to a key doesn't require // a localKeyID and will confuse some PKCS12 implementations. // // If we find one, we'll prune it out. if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id)) { continue; } Asn1Encodable entry = cert[oid]; // NB: Ignore any existing FriendlyName if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id)) { continue; } fName.Add(new DerSequence(new DerObjectIdentifier(oid), new DerSet(entry))); } // // make sure we are using the local alias on store // // NB: We always set the FriendlyName based on 'certId' //if (cert[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] == null) { //fName.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(certId)))); fName.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(CreateSubjectKeyID(cert.Certificate.GetPublicKey()).GetKeyIdentifier())))); } SafeBag sBag = new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName)); certSeq.Add(sBag); doneCerts.Add(cert.Certificate); } var chainCerts = store.Aliases.OfType <string>().Select(store.GetCertificateChain).Aggregate <IEnumerable <X509CertificateEntry>, IEnumerable <X509CertificateEntry> >(new List <X509CertificateEntry>(), (list, entries) => list.Union(entries)); foreach (var cert in chainCerts) { //X509CertificateEntry cert = (X509CertificateEntry)chainCerts[certId]; if (doneCerts.Contains(cert.Certificate)) { continue; } CertBag cBag = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(cert.Certificate.GetEncoded())); Asn1EncodableVector fName = new Asn1EncodableVector(); foreach (string oid in cert.BagAttributeKeys) { // a certificate not immediately linked to a key doesn't require // a localKeyID and will confuse some PKCS12 implementations. // // If we find one, we'll prune it out. if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id)) { continue; } fName.Add(new DerSequence(new DerObjectIdentifier(oid), new DerSet(cert[oid]))); } SafeBag sBag = new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName)); certSeq.Add(sBag); } derEncodedBytes = new DerSequence(certSeq).GetDerEncoded(); Func <bool, AlgorithmIdentifier, char[], bool, byte[], byte[]> CryptPbeData = (forEncryption_, algId_, password_, wrongPkcs12Zero_, data_) => { var method = T.GetMethod("CryptPbeData", BindingFlags.NonPublic | BindingFlags.Static); return((byte[])method.Invoke(store, new object[] { forEncryption_, algId_, password_, wrongPkcs12Zero_, data_ })); }; ContentInfo[] info = null; if (null != encryptionPassword) { byte[] certBytes = CryptPbeData(true, cAlgId, encryptionPassword.ToArray(), false, derEncodedBytes); var cInfo = new EncryptedData(PkcsObjectIdentifiers.Data, cAlgId, new BerOctetString(certBytes)); info = new ContentInfo[] { new ContentInfo(PkcsObjectIdentifiers.Data, keyString), new ContentInfo(PkcsObjectIdentifiers.EncryptedData, cInfo.ToAsn1Object()) }; } else { var cInfo = new BerOctetString(derEncodedBytes); info = new ContentInfo[] { new ContentInfo(PkcsObjectIdentifiers.Data, keyString), new ContentInfo(PkcsObjectIdentifiers.Data, cInfo.ToAsn1Object()) }; } byte[] data = new AuthenticatedSafe(info).GetEncoded(Asn1Encodable.Der); ContentInfo mainInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(data)); // // create the mac // byte[] mSalt = new byte[saltSize]; random.NextBytes(mSalt); Func <DerObjectIdentifier, byte[], int, char[], bool, byte[], byte[]> CalculatePbeMac = (oid_, salt_, itCount_, password_, wrongPkcs12Zero_, data_) => { var method = T.GetMethod("CalculatePbeMac", BindingFlags.NonPublic | BindingFlags.Static); return((byte[])method.Invoke(store, new object[] { oid_, salt_, itCount_, password_, wrongPkcs12Zero_, data_ })); }; MacData mData = null; if (null != integrityPassword) { //byte[] mac = CalculatePbeMac(OiwObjectIdentifiers.IdSha1, mSalt, minIterations, integrityPassword.ToArray(), false, data); byte[] mac = CalculatePbeMac(PbeUtilities.GetObjectIdentifier("PBEwithHmacSHA-256"), mSalt, minIterations, integrityPassword.ToArray(), false, data); //AlgorithmIdentifier algId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); AlgorithmIdentifier algId = new AlgorithmIdentifier(PbeUtilities.GetObjectIdentifier("PBEwithHmacSHA-256"), DerNull.Instance); DigestInfo dInfo = new DigestInfo(algId, mac); mData = new MacData(dInfo, mSalt, minIterations); } // // output the Pfx // Pfx pfx = new Pfx(mainInfo, mData); DerOutputStream derOut = new DerOutputStream(stream); derOut.WriteObject(pfx); }
/** * Creates a CertPath of the specified type. * This constructor is protected because most users should use * a CertificateFactory to create CertPaths. * * @param type the standard name of the type of Certificatesin this path **/ public PkixCertPath( Stream inStream, String encoding) // : base("X.509") { try { if (encoding.ToUpper().Equals("PkiPath".ToUpper())) { Asn1InputStream derInStream = new Asn1InputStream(inStream); Asn1Object derObject = derInStream.ReadObject(); if (!(derObject is Asn1Sequence)) { throw new CertificateException( "input stream does not contain a ASN1 SEQUENCE while reading PkiPath encoded data to load CertPath"); } IEnumerator e = ((Asn1Sequence)derObject).GetEnumerator(); Stream certInStream; MemoryStream outStream; DerOutputStream derOutStream; certificates = new ArrayList(); while (e.MoveNext()) { outStream = new MemoryStream(); derOutStream = new DerOutputStream(outStream); derOutStream.WriteObject((Asn1Encodable)e.Current); derOutStream.Close(); certInStream = new MemoryStream(outStream.ToArray(), false); certificates.Insert(0, new X509CertificateParser().ReadCertificate(certInStream)); } } else if (encoding.ToUpper().Equals("PKCS7") || encoding.ToUpper().Equals("PEM")) { inStream = new BufferedStream(inStream); certificates = new ArrayList(); X509CertificateParser certParser = new X509CertificateParser(); X509Certificate cert = null; while ((cert = certParser.ReadCertificate(inStream)) != null) { certificates.Add(cert); } } else { throw new CertificateException("unsupported encoding: " + encoding); } } catch (IOException ex) { throw new CertificateException( "IOException throw while decoding CertPath:\n" + ex.ToString()); } this.certificates = SortCerts(certificates); }
/// <exception cref="System.IO.IOException"></exception> public virtual byte[] GetArchiveTimestampData(int index, Document originalDocument ) { ByteArrayOutputStream toTimestamp = new ByteArrayOutputStream(); BcCms.ContentInfo contentInfo = cmsSignedData.ContentInfo; BcCms.SignedData signedData = BcCms.SignedData.GetInstance(contentInfo.Content); // 5.4.1 if (signedData.EncapContentInfo == null || signedData.EncapContentInfo. Content == null) { if (originalDocument != null) { //jbonilla Hack para leer un InputStream en su totalidad. toTimestamp.Write(Streams.ReadAll( originalDocument.OpenStream())); } else { throw new RuntimeException("Signature is detached and no original data provided." ); } } else { BcCms.ContentInfo content = signedData.EncapContentInfo; DerOctetString octet = (DerOctetString)content.Content; BcCms.ContentInfo info2 = new BcCms.ContentInfo(new DerObjectIdentifier("1.2.840.113549.1.7.1" ), new BerOctetString(octet.GetOctets())); toTimestamp.Write(info2.GetEncoded()); } if (signedData.Certificates != null) { DerOutputStream output = new DerOutputStream(toTimestamp); output.WriteObject(signedData.Certificates); output.Close(); } if (signedData.CRLs != null) { toTimestamp.Write(signedData.CRLs.GetEncoded()); } if (signerInformation.UnsignedAttributes != null) { Asn1EncodableVector original = signerInformation.UnsignedAttributes.ToAsn1EncodableVector (); IList <BcCms.Attribute> timeStampToRemove = GetTimeStampToRemove(index); Asn1EncodableVector filtered = new Asn1EncodableVector(); for (int i = 0; i < original.Count; i++) { Asn1Encodable enc = original[i]; if (!timeStampToRemove.Contains(enc)) { filtered.Add(original[i]); } } SignerInformation filteredInfo = SignerInformation.ReplaceUnsignedAttributes(signerInformation , new BcCms.AttributeTable(filtered)); toTimestamp.Write(filteredInfo.ToSignerInfo().GetEncoded()); } return(toTimestamp.ToByteArray()); }