示例#1
0
		public MacData(
            DigestInfo	digInfo,
            byte[]		salt,
            int			iterationCount)
        {
            this.digInfo = digInfo;
            this.salt = (byte[]) salt.Clone();
            this.iterationCount = BigInteger.ValueOf(iterationCount);
        }
示例#2
0
		private MacData(
            Asn1Sequence seq)
        {
            this.digInfo = DigestInfo.GetInstance(seq[0]);
            this.salt = ((Asn1OctetString) seq[1]).GetOctets();

			if (seq.Count == 3)
            {
                this.iterationCount = ((DerInteger) seq[2]).Value;
            }
            else
            {
                this.iterationCount = BigInteger.One;
            }
        }
		/**
		* Re-encode the PKCS#12 structure to definite length encoding at the inner layer
		* as well, recomputing the MAC accordingly.
		*
		* @param berPKCS12File - original PKCS12 file.
		* @param provider - provider to use for MAC calculation.
		* @return a byte array representing the DER encoding of the PFX structure.
		* @throws IOException on parsing, encoding errors.
		*/
		public static byte[] ConvertToDefiniteLength(
			byte[]	berPkcs12File,
			char[]	passwd)
		{
			Pfx pfx = new Pfx(Asn1Sequence.GetInstance(Asn1Object.FromByteArray(berPkcs12File)));

			ContentInfo info = pfx.AuthSafe;

			Asn1OctetString content = Asn1OctetString.GetInstance(info.Content);
			Asn1Object obj = Asn1Object.FromByteArray(content.GetOctets());

			info = new ContentInfo(info.ContentType, new DerOctetString(obj.GetEncoded(Asn1Encodable.Der)));

			MacData mData = pfx.MacData;

			try
			{
				int itCount = mData.IterationCount.IntValue;
				byte[] data = Asn1OctetString.GetInstance(info.Content).GetOctets();
				byte[] res = Pkcs12Store.CalculatePbeMac(
					mData.Mac.AlgorithmID.ObjectID, mData.GetSalt(), itCount, passwd, false, data);

				AlgorithmIdentifier algId = new AlgorithmIdentifier(
					mData.Mac.AlgorithmID.ObjectID, DerNull.Instance);
				DigestInfo dInfo = new DigestInfo(algId, res);

				mData = new MacData(dInfo, mData.GetSalt(), itCount);
			}
			catch (Exception e)
			{
				throw new IOException("error constructing MAC: " + e.ToString());
			}

			pfx = new Pfx(info, mData);

			return pfx.GetEncoded(Asn1Encodable.Der);
		}
示例#4
0
        public void Save(Stream stream, char[] password, SecureRandom random)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (password == null)
            {
                throw new ArgumentNullException("password");
            }
            if (random == null)
            {
                throw new ArgumentNullException("random");
            }

            //
            // handle the key
            //
            var keyS = new Asn1EncodableVector();
            foreach (string name in _keys.Keys)
            {
                var kSalt = new byte[SaltSize];
                random.NextBytes(kSalt);

                var privKey = (AsymmetricKeyEntry) _keys[name];
                EncryptedPrivateKeyInfo kInfo = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(_keyAlgorithm, password, kSalt, MinIterations, privKey.Key);

                var 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 = GetCertificate(name);
                    AsymmetricKeyParameter pubKey = ct.Certificate.GetPublicKey();
                    SubjectKeyIdentifier subjectKeyID = CreateSubjectKeyID(pubKey);

                    kName.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID, new DerSet(subjectKeyID)));
                }

                var kBag = new SafeBag(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag, kInfo.ToAsn1Object(), new DerSet(kName));
                keyS.Add(kBag);
            }

            byte[] derEncodedBytes = new DerSequence(keyS).GetDerEncoded();

            var keyString = new BerOctetString(derEncodedBytes);

            //
            // certificate processing
            //
            var cSalt = new byte[SaltSize];

            random.NextBytes(cSalt);

            var certSeq = new Asn1EncodableVector();
            var cParams = new Pkcs12PbeParams(cSalt, MinIterations);
            var cAlgId = new AlgorithmIdentifier(_certAlgorithm, cParams.ToAsn1Object());
            ISet doneCerts = new HashSet();

            foreach (string name in _keys.Keys)
            {
                X509CertificateEntry certEntry = GetCertificate(name);
                var cBag = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(certEntry.Certificate.GetEncoded()));

                var 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)));
                }

                var sBag = new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName));

                certSeq.Add(sBag);

                doneCerts.Add(certEntry.Certificate);
            }

            foreach (string certId in _certs.Keys)
            {
                var cert = (X509CertificateEntry) _certs[certId];

                if (_keys[certId] != null)
                {
                    continue;
                }

                var cBag = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(cert.Certificate.GetEncoded()));

                var 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))));
                }

                var sBag = new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName));

                certSeq.Add(sBag);

                doneCerts.Add(cert.Certificate);
            }

            foreach (CertId certId in _chainCerts.Keys)
            {
                var cert = (X509CertificateEntry) _chainCerts[certId];

                if (doneCerts.Contains(cert.Certificate))
                {
                    continue;
                }

                var cBag = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(cert.Certificate.GetEncoded()));

                var 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])));
                }

                var sBag = new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName));

                certSeq.Add(sBag);
            }

            derEncodedBytes = new DerSequence(certSeq).GetDerEncoded();

            byte[] certBytes = CryptPbeData(true, cAlgId, password, false, derEncodedBytes);

            var cInfo = new EncryptedData(PkcsObjectIdentifiers.Data, cAlgId, new BerOctetString(certBytes));

            ContentInfo[] info = {new ContentInfo(PkcsObjectIdentifiers.Data, keyString), new ContentInfo(PkcsObjectIdentifiers.EncryptedData, cInfo.ToAsn1Object())};

            byte[] data = new AuthenticatedSafe(info).GetEncoded(_useDerEncoding ? Asn1Encodable.Der : Asn1Encodable.Ber);

            var mainInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(data));

            //
            // create the mac
            //
            var mSalt = new byte[20];
            random.NextBytes(mSalt);

            byte[] mac = CalculatePbeMac(OiwObjectIdentifiers.IdSha1, mSalt, MinIterations, password, false, data);

            var algId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
            var dInfo = new DigestInfo(algId, mac);

            var mData = new MacData(dInfo, mSalt, MinIterations);

            //
            // output the Pfx
            //
            var pfx = new Pfx(mainInfo, mData);

            DerOutputStream derOut;
            if (_useDerEncoding)
            {
                derOut = new DerOutputStream(stream);
            }
            else
            {
                derOut = new BerOutputStream(stream);
            }

            derOut.WriteObject(pfx);
        }
		private byte[] DerEncode(byte[] hash)
		{
			if (algId == null)
			{
				// For raw RSA, the DigestInfo must be prepared externally
				return hash;
			}

			DigestInfo dInfo = new DigestInfo(algId, hash);

			return dInfo.GetDerEncoded();
		}
            public SignerInfo Generate(DerObjectIdentifier contentType, AlgorithmIdentifier digestAlgorithm, byte[] calculatedDigest)
            {
                try
                {
                    string digestName = Helper.GetDigestAlgName(_digestOID);
                    string signatureName = digestName + "with" + _encName;

//					AlgorithmIdentifier digAlgId = DigestAlgorithmID;
//
//					byte[] hash = (byte[])outer._messageHashes[Helper.GetDigestAlgName(this._digestOID)];
//					outer._digests[_digestOID] = hash.Clone();

                    byte[] bytesToSign = calculatedDigest;

                    /* RFC 3852 5.4
                     * The result of the message digest calculation process depends on
                     * whether the signedAttrs field is present.  When the field is absent,
                     * the result is just the message digest of the content as described
                     *
                     * above.  When the field is present, however, the result is the message
                     * digest of the complete DER encoding of the SignedAttrs value
                     * contained in the signedAttrs field.
                     */
                    Asn1Set signedAttr = null;
                    if (_sAttr != null)
                    {
                        IDictionary parameters = _outer.GetBaseParameters(contentType, digestAlgorithm, calculatedDigest);

//						Asn1.Cms.AttributeTable signed = _sAttr.GetAttributes(Collections.unmodifiableMap(parameters));
                        Asn1.Cms.AttributeTable signed = _sAttr.GetAttributes(parameters);

                        if (contentType == null) //counter signature
                        {
                            if (signed != null && signed[CmsAttributes.ContentType] != null)
                            {
                                IDictionary tmpSigned = signed.ToDictionary();
                                tmpSigned.Remove(CmsAttributes.ContentType);
                                signed = new Asn1.Cms.AttributeTable(tmpSigned);
                            }
                        }

                        signedAttr = _outer.GetAttributeSet(signed);

                        // sig must be composed from the DER encoding.
                        bytesToSign = signedAttr.GetEncoded(Asn1Encodable.Der);
                    }
                    else
                    {
                        // Note: Need to use raw signatures here since we have already calculated the digest
                        if (_encName.Equals("RSA"))
                        {
                            var dInfo = new DigestInfo(digestAlgorithm, calculatedDigest);
                            bytesToSign = dInfo.GetEncoded(Asn1Encodable.Der);
                        }
                    }

                    _sig.BlockUpdate(bytesToSign, 0, bytesToSign.Length);
                    byte[] sigBytes = _sig.GenerateSignature();

                    Asn1Set unsignedAttr = null;
                    if (_unsAttr != null)
                    {
                        IDictionary parameters = _outer.GetBaseParameters(contentType, digestAlgorithm, calculatedDigest);
                        parameters[CmsAttributeTableParameter.Signature] = sigBytes.Clone();

//						Asn1.Cms.AttributeTable unsigned = _unsAttr.getAttributes(Collections.unmodifiableMap(parameters));
                        Asn1.Cms.AttributeTable unsigned = _unsAttr.GetAttributes(parameters);

                        unsignedAttr = _outer.GetAttributeSet(unsigned);
                    }

                    // TODO[RSAPSS] Need the ability to specify non-default parameters
                    Asn1Encodable sigX509Parameters = SignerUtilities.GetDefaultX509Parameters(signatureName);
                    AlgorithmIdentifier digestEncryptionAlgorithm = GetEncAlgorithmIdentifier(new DerObjectIdentifier(_encOID), sigX509Parameters);

                    return new SignerInfo(_signerIdentifier, digestAlgorithm, signedAttr, digestEncryptionAlgorithm, new DerOctetString(sigBytes), unsignedAttr);
                }
                catch (IOException e)
                {
                    throw new CmsStreamException("encoding error.", e);
                }
                catch (SignatureException e)
                {
                    throw new CmsStreamException("error creating signature.", e);
                }
            }