Search in sources :

Example 1 with TeeOutputStream

use of com.github.zhenwei.core.util.io.TeeOutputStream in project LinLong-Java by zhenwei1108.

the class SignerInformation method doVerify.

private boolean doVerify(SignerInformationVerifier verifier) throws CMSException {
    String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID());
    ContentVerifier contentVerifier;
    try {
        contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, info.getDigestAlgorithm());
    } catch (OperatorCreationException e) {
        throw new CMSException("can't create content verifier: " + e.getMessage(), e);
    }
    try {
        OutputStream sigOut = contentVerifier.getOutputStream();
        if (resultDigest == null) {
            DigestCalculator calc = verifier.getDigestCalculator(this.getDigestAlgorithmID());
            if (content != null) {
                OutputStream digOut = calc.getOutputStream();
                if (signedAttributeSet == null) {
                    if (contentVerifier instanceof RawContentVerifier) {
                        content.write(digOut);
                    } else {
                        OutputStream cOut = new TeeOutputStream(digOut, sigOut);
                        content.write(cOut);
                        cOut.close();
                    }
                } else {
                    content.write(digOut);
                    sigOut.write(this.getEncodedSignedAttributes());
                }
                digOut.close();
            } else if (signedAttributeSet != null) {
                sigOut.write(this.getEncodedSignedAttributes());
            } else {
                // TODO Get rid of this exception and just treat content==null as empty not missing?
                throw new CMSException("data not encapsulated in signature - use detached constructor.");
            }
            resultDigest = calc.getDigest();
        } else {
            if (signedAttributeSet == null) {
                if (content != null) {
                    content.write(sigOut);
                }
            } else {
                sigOut.write(this.getEncodedSignedAttributes());
            }
        }
        sigOut.close();
    } catch (IOException e) {
        throw new CMSException("can't process mime object to create signature.", e);
    } catch (OperatorCreationException e) {
        throw new CMSException("can't create digest calculator: " + e.getMessage(), e);
    }
    // RFC 3852 11.1 Check the content-type attribute is correct
    verifyContentTypeAttributeValue();
    AttributeTable signedAttrTable = this.getSignedAttributes();
    // RFC 6211 Validate Algorithm Identifier protection attribute if present
    verifyAlgorithmIdentifierProtectionAttribute(signedAttrTable);
    // RFC 3852 11.2 Check the message-digest attribute is correct
    verifyMessageDigestAttribute();
    // RFC 3852 11.4 Validate countersignature attribute(s)
    verifyCounterSignatureAttribute(signedAttrTable);
    try {
        if (signedAttributeSet == null && resultDigest != null) {
            if (contentVerifier instanceof RawContentVerifier) {
                RawContentVerifier rawVerifier = (RawContentVerifier) contentVerifier;
                if (encName.equals("RSA")) {
                    DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(digestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest);
                    return rawVerifier.verify(digInfo.getEncoded(ASN1Encoding.DER), this.getSignature());
                }
                return rawVerifier.verify(resultDigest, this.getSignature());
            }
        }
        return contentVerifier.verify(this.getSignature());
    } catch (IOException e) {
        throw new CMSException("can't process mime object to create signature.", e);
    }
}
Also used : TeeOutputStream(com.github.zhenwei.core.util.io.TeeOutputStream) DigestInfo(com.github.zhenwei.core.asn1.x509.DigestInfo) RawContentVerifier(com.github.zhenwei.pkix.operator.RawContentVerifier) ContentVerifier(com.github.zhenwei.pkix.operator.ContentVerifier) TeeOutputStream(com.github.zhenwei.core.util.io.TeeOutputStream) OutputStream(java.io.OutputStream) DigestCalculator(com.github.zhenwei.pkix.operator.DigestCalculator) AttributeTable(com.github.zhenwei.pkix.util.asn1.cms.AttributeTable) RawContentVerifier(com.github.zhenwei.pkix.operator.RawContentVerifier) ASN1OctetString(com.github.zhenwei.core.asn1.ASN1OctetString) IOException(java.io.IOException) OperatorCreationException(com.github.zhenwei.pkix.operator.OperatorCreationException) AlgorithmIdentifier(com.github.zhenwei.core.asn1.x509.AlgorithmIdentifier)

Example 2 with TeeOutputStream

use of com.github.zhenwei.core.util.io.TeeOutputStream in project LinLong-Java by zhenwei1108.

the class CMSAuthenticatedDataGenerator method generate.

/**
 * Generate an authenticated data object from the passed in typedData and MacCalculator.
 *
 * @param typedData        the data to have a MAC attached.
 * @param macCalculator    the calculator of the MAC to be attached.
 * @param digestCalculator calculator for computing digest of the encapsulated data.
 * @return the resulting CMSAuthenticatedData object.
 * @throws CMSException on failure in encoding data or processing recipients.
 */
public CMSAuthenticatedData generate(CMSTypedData typedData, MacCalculator macCalculator, final DigestCalculator digestCalculator) throws CMSException {
    ASN1EncodableVector recipientInfos = new ASN1EncodableVector();
    ASN1OctetString encContent;
    ASN1OctetString macResult;
    for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext(); ) {
        RecipientInfoGenerator recipient = (RecipientInfoGenerator) it.next();
        recipientInfos.add(recipient.generate(macCalculator.getKey()));
    }
    AuthenticatedData authData;
    if (digestCalculator != null) {
        try {
            ByteArrayOutputStream bOut = new ByteArrayOutputStream();
            OutputStream out = new TeeOutputStream(digestCalculator.getOutputStream(), bOut);
            typedData.write(out);
            out.close();
            encContent = new BEROctetString(bOut.toByteArray());
        } catch (IOException e) {
            throw new CMSException("unable to perform digest calculation: " + e.getMessage(), e);
        }
        Map parameters = Collections.unmodifiableMap(getBaseParameters(typedData.getContentType(), digestCalculator.getAlgorithmIdentifier(), macCalculator.getAlgorithmIdentifier(), digestCalculator.getDigest()));
        if (authGen == null) {
            authGen = new DefaultAuthenticatedAttributeTableGenerator();
        }
        ASN1Set authed = new DERSet(authGen.getAttributes(parameters).toASN1EncodableVector());
        try {
            OutputStream mOut = macCalculator.getOutputStream();
            mOut.write(authed.getEncoded(ASN1Encoding.DER));
            mOut.close();
            macResult = new DEROctetString(macCalculator.getMac());
        } catch (IOException e) {
            throw new CMSException("unable to perform MAC calculation: " + e.getMessage(), e);
        }
        ASN1Set unauthed = (unauthGen != null) ? new BERSet(unauthGen.getAttributes(parameters).toASN1EncodableVector()) : null;
        ContentInfo eci = new ContentInfo(typedData.getContentType(), encContent);
        authData = new AuthenticatedData(originatorInfo, new DERSet(recipientInfos), macCalculator.getAlgorithmIdentifier(), digestCalculator.getAlgorithmIdentifier(), eci, authed, macResult, unauthed);
    } else {
        try {
            ByteArrayOutputStream bOut = new ByteArrayOutputStream();
            OutputStream mOut = new TeeOutputStream(bOut, macCalculator.getOutputStream());
            typedData.write(mOut);
            mOut.close();
            encContent = new BEROctetString(bOut.toByteArray());
            macResult = new DEROctetString(macCalculator.getMac());
        } catch (IOException e) {
            throw new CMSException("unable to perform MAC calculation: " + e.getMessage(), e);
        }
        ASN1Set unauthed = (unauthGen != null) ? new BERSet(unauthGen.getAttributes(Collections.EMPTY_MAP).toASN1EncodableVector()) : null;
        ContentInfo eci = new ContentInfo(typedData.getContentType(), encContent);
        authData = new AuthenticatedData(originatorInfo, new DERSet(recipientInfos), macCalculator.getAlgorithmIdentifier(), null, eci, null, macResult, unauthed);
    }
    ContentInfo contentInfo = new ContentInfo(CMSObjectIdentifiers.authenticatedData, authData);
    return new CMSAuthenticatedData(contentInfo, new DigestCalculatorProvider() {

        public DigestCalculator get(AlgorithmIdentifier digestAlgorithmIdentifier) throws OperatorCreationException {
            return digestCalculator;
        }
    });
}
Also used : ASN1OctetString(com.github.zhenwei.core.asn1.ASN1OctetString) BERSet(com.github.zhenwei.core.asn1.BERSet) TeeOutputStream(com.github.zhenwei.core.util.io.TeeOutputStream) OutputStream(java.io.OutputStream) TeeOutputStream(com.github.zhenwei.core.util.io.TeeOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) DigestCalculator(com.github.zhenwei.pkix.operator.DigestCalculator) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) DERSet(com.github.zhenwei.core.asn1.DERSet) DEROctetString(com.github.zhenwei.core.asn1.DEROctetString) AlgorithmIdentifier(com.github.zhenwei.core.asn1.x509.AlgorithmIdentifier) BEROctetString(com.github.zhenwei.core.asn1.BEROctetString) ASN1Set(com.github.zhenwei.core.asn1.ASN1Set) DigestCalculatorProvider(com.github.zhenwei.pkix.operator.DigestCalculatorProvider) ContentInfo(com.github.zhenwei.pkix.util.asn1.cms.ContentInfo) AuthenticatedData(com.github.zhenwei.pkix.util.asn1.cms.AuthenticatedData) Iterator(java.util.Iterator) ASN1EncodableVector(com.github.zhenwei.core.asn1.ASN1EncodableVector) OperatorCreationException(com.github.zhenwei.pkix.operator.OperatorCreationException) Map(java.util.Map)

Example 3 with TeeOutputStream

use of com.github.zhenwei.core.util.io.TeeOutputStream in project LinLong-Java by zhenwei1108.

the class JcaContentSignerBuilder method buildComposite.

private ContentSigner buildComposite(CompositePrivateKey privateKey) throws OperatorCreationException {
    try {
        List<PrivateKey> privateKeys = privateKey.getPrivateKeys();
        final ASN1Sequence sigAlgIds = ASN1Sequence.getInstance(sigAlgId.getParameters());
        final Signature[] sigs = new Signature[sigAlgIds.size()];
        for (int i = 0; i != sigAlgIds.size(); i++) {
            sigs[i] = helper.createSignature(AlgorithmIdentifier.getInstance(sigAlgIds.getObjectAt(i)));
            if (random != null) {
                sigs[i].initSign(privateKeys.get(i), random);
            } else {
                sigs[i].initSign(privateKeys.get(i));
            }
        }
        OutputStream sStream = OutputStreamFactory.createStream(sigs[0]);
        for (int i = 1; i != sigs.length; i++) {
            sStream = new TeeOutputStream(sStream, OutputStreamFactory.createStream(sigs[i]));
        }
        final OutputStream sigStream = sStream;
        return new ContentSigner() {

            OutputStream stream = sigStream;

            public AlgorithmIdentifier getAlgorithmIdentifier() {
                return sigAlgId;
            }

            public OutputStream getOutputStream() {
                return stream;
            }

            public byte[] getSignature() {
                try {
                    ASN1EncodableVector sigV = new ASN1EncodableVector();
                    for (int i = 0; i != sigs.length; i++) {
                        sigV.add(new DERBitString(sigs[i].sign()));
                    }
                    return new DERSequence(sigV).getEncoded(ASN1Encoding.DER);
                } catch (IOException e) {
                    throw new RuntimeOperatorException("exception encoding signature: " + e.getMessage(), e);
                } catch (SignatureException e) {
                    throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e);
                }
            }
        };
    } catch (GeneralSecurityException e) {
        throw new OperatorCreationException("cannot create signer: " + e.getMessage(), e);
    }
}
Also used : TeeOutputStream(com.github.zhenwei.core.util.io.TeeOutputStream) PrivateKey(java.security.PrivateKey) CompositePrivateKey(com.github.zhenwei.provider.jcajce.CompositePrivateKey) TeeOutputStream(com.github.zhenwei.core.util.io.TeeOutputStream) OutputStream(java.io.OutputStream) GeneralSecurityException(java.security.GeneralSecurityException) ContentSigner(com.github.zhenwei.pkix.operator.ContentSigner) DERBitString(com.github.zhenwei.core.asn1.DERBitString) IOException(java.io.IOException) SignatureException(java.security.SignatureException) ASN1Sequence(com.github.zhenwei.core.asn1.ASN1Sequence) DERSequence(com.github.zhenwei.core.asn1.DERSequence) RuntimeOperatorException(com.github.zhenwei.pkix.operator.RuntimeOperatorException) Signature(java.security.Signature) ASN1EncodableVector(com.github.zhenwei.core.asn1.ASN1EncodableVector) OperatorCreationException(com.github.zhenwei.pkix.operator.OperatorCreationException)

Example 4 with TeeOutputStream

use of com.github.zhenwei.core.util.io.TeeOutputStream in project LinLong-Java by zhenwei1108.

the class CMSAuthenticatedDataStreamGenerator method open.

/**
 * generate an authenticated data structure with the encapsulated bytes marked as type dataType.
 *
 * @param dataType         the type of the data been written to the object.
 * @param out              the stream to store the authenticated structure in.
 * @param macCalculator    calculator for the MAC to be attached to the data.
 * @param digestCalculator calculator for computing digest of the encapsulated data.
 */
public OutputStream open(ASN1ObjectIdentifier dataType, OutputStream out, MacCalculator macCalculator, DigestCalculator digestCalculator) throws CMSException {
    this.macCalculator = macCalculator;
    try {
        ASN1EncodableVector recipientInfos = new ASN1EncodableVector();
        for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext(); ) {
            RecipientInfoGenerator recipient = (RecipientInfoGenerator) it.next();
            recipientInfos.add(recipient.generate(macCalculator.getKey()));
        }
        // 
        // ContentInfo
        // 
        BERSequenceGenerator cGen = new BERSequenceGenerator(out);
        cGen.addObject(CMSObjectIdentifiers.authenticatedData);
        // 
        // Authenticated Data
        // 
        BERSequenceGenerator authGen = new BERSequenceGenerator(cGen.getRawOutputStream(), 0, true);
        authGen.addObject(new ASN1Integer(AuthenticatedData.calculateVersion(originatorInfo)));
        if (originatorInfo != null) {
            authGen.addObject(new DERTaggedObject(false, 0, originatorInfo));
        }
        if (berEncodeRecipientSet) {
            authGen.getRawOutputStream().write(new BERSet(recipientInfos).getEncoded());
        } else {
            authGen.getRawOutputStream().write(new DERSet(recipientInfos).getEncoded());
        }
        AlgorithmIdentifier macAlgId = macCalculator.getAlgorithmIdentifier();
        authGen.getRawOutputStream().write(macAlgId.getEncoded());
        if (digestCalculator != null) {
            authGen.addObject(new DERTaggedObject(false, 1, digestCalculator.getAlgorithmIdentifier()));
        }
        BERSequenceGenerator eiGen = new BERSequenceGenerator(authGen.getRawOutputStream());
        eiGen.addObject(dataType);
        OutputStream octetStream = CMSUtils.createBEROctetOutputStream(eiGen.getRawOutputStream(), 0, true, bufferSize);
        OutputStream mOut;
        if (digestCalculator != null) {
            mOut = new TeeOutputStream(octetStream, digestCalculator.getOutputStream());
        } else {
            mOut = new TeeOutputStream(octetStream, macCalculator.getOutputStream());
        }
        return new CmsAuthenticatedDataOutputStream(macCalculator, digestCalculator, dataType, mOut, cGen, authGen, eiGen);
    } catch (IOException e) {
        throw new CMSException("exception decoding algorithm parameters.", e);
    }
}
Also used : BERSet(com.github.zhenwei.core.asn1.BERSet) TeeOutputStream(com.github.zhenwei.core.util.io.TeeOutputStream) DERTaggedObject(com.github.zhenwei.core.asn1.DERTaggedObject) OutputStream(java.io.OutputStream) TeeOutputStream(com.github.zhenwei.core.util.io.TeeOutputStream) ASN1Integer(com.github.zhenwei.core.asn1.ASN1Integer) IOException(java.io.IOException) DERSet(com.github.zhenwei.core.asn1.DERSet) AlgorithmIdentifier(com.github.zhenwei.core.asn1.x509.AlgorithmIdentifier) BERSequenceGenerator(com.github.zhenwei.core.asn1.BERSequenceGenerator) Iterator(java.util.Iterator) ASN1EncodableVector(com.github.zhenwei.core.asn1.ASN1EncodableVector)

Example 5 with TeeOutputStream

use of com.github.zhenwei.core.util.io.TeeOutputStream in project LinLong-Java by zhenwei1108.

the class BcKeyStoreSpi method engineStore.

public void engineStore(OutputStream stream, char[] password) throws IOException {
    DataOutputStream dOut = new DataOutputStream(stream);
    byte[] salt = new byte[STORE_SALT_SIZE];
    int iterationCount = MIN_ITERATIONS + (random.nextInt() & 0x3ff);
    random.nextBytes(salt);
    dOut.writeInt(version);
    dOut.writeInt(salt.length);
    dOut.write(salt);
    dOut.writeInt(iterationCount);
    HMac hMac = new HMac(new SHA1Digest());
    MacOutputStream mOut = new MacOutputStream(hMac);
    PBEParametersGenerator pbeGen = new PKCS12ParametersGenerator(new SHA1Digest());
    byte[] passKey = PBEParametersGenerator.PKCS12PasswordToBytes(password);
    pbeGen.init(passKey, salt, iterationCount);
    if (version < 2) {
        hMac.init(pbeGen.generateDerivedMacParameters(hMac.getMacSize()));
    } else {
        hMac.init(pbeGen.generateDerivedMacParameters(hMac.getMacSize() * 8));
    }
    for (int i = 0; i != passKey.length; i++) {
        passKey[i] = 0;
    }
    saveStore(new TeeOutputStream(dOut, mOut));
    byte[] mac = new byte[hMac.getMacSize()];
    hMac.doFinal(mac, 0);
    dOut.write(mac);
    dOut.close();
}
Also used : TeeOutputStream(com.github.zhenwei.core.util.io.TeeOutputStream) PKCS12ParametersGenerator(com.github.zhenwei.core.crypto.generators.PKCS12ParametersGenerator) DataOutputStream(java.io.DataOutputStream) HMac(com.github.zhenwei.core.crypto.macs.HMac) SHA1Digest(com.github.zhenwei.core.crypto.digests.SHA1Digest) MacOutputStream(com.github.zhenwei.core.crypto.io.MacOutputStream) PBEParametersGenerator(com.github.zhenwei.core.crypto.PBEParametersGenerator)

Aggregations

TeeOutputStream (com.github.zhenwei.core.util.io.TeeOutputStream)5 IOException (java.io.IOException)4 OutputStream (java.io.OutputStream)4 ASN1EncodableVector (com.github.zhenwei.core.asn1.ASN1EncodableVector)3 AlgorithmIdentifier (com.github.zhenwei.core.asn1.x509.AlgorithmIdentifier)3 OperatorCreationException (com.github.zhenwei.pkix.operator.OperatorCreationException)3 ASN1OctetString (com.github.zhenwei.core.asn1.ASN1OctetString)2 BERSet (com.github.zhenwei.core.asn1.BERSet)2 DERSet (com.github.zhenwei.core.asn1.DERSet)2 DigestCalculator (com.github.zhenwei.pkix.operator.DigestCalculator)2 Iterator (java.util.Iterator)2 ASN1Integer (com.github.zhenwei.core.asn1.ASN1Integer)1 ASN1Sequence (com.github.zhenwei.core.asn1.ASN1Sequence)1 ASN1Set (com.github.zhenwei.core.asn1.ASN1Set)1 BEROctetString (com.github.zhenwei.core.asn1.BEROctetString)1 BERSequenceGenerator (com.github.zhenwei.core.asn1.BERSequenceGenerator)1 DERBitString (com.github.zhenwei.core.asn1.DERBitString)1 DEROctetString (com.github.zhenwei.core.asn1.DEROctetString)1 DERSequence (com.github.zhenwei.core.asn1.DERSequence)1 DERTaggedObject (com.github.zhenwei.core.asn1.DERTaggedObject)1