All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xwiki.crypto.signer.internal.cms.DefaultCMSSignedDataVerifier Maven / Gradle / Ivy

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.xwiki.crypto.signer.internal.cms;

import java.security.GeneralSecurityException;
import java.util.Collection;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.operator.DigestCalculatorProvider;
import org.xwiki.component.annotation.Component;
import org.xwiki.component.manager.ComponentManager;
import org.xwiki.component.phase.Initializable;
import org.xwiki.component.phase.InitializationException;
import org.xwiki.crypto.DigestFactory;
import org.xwiki.crypto.pkix.CertificateChainBuilder;
import org.xwiki.crypto.pkix.CertificateFactory;
import org.xwiki.crypto.pkix.CertificateProvider;
import org.xwiki.crypto.pkix.params.CertifiedPublicKey;
import org.xwiki.crypto.signer.CMSSignedDataVerifier;
import org.xwiki.crypto.signer.internal.BcContentVerifierProviderBuilder;
import org.xwiki.crypto.signer.param.CMSSignedDataVerified;

/**
 * Default implementation of {@link CMSSignedDataVerifier} based on Bouncy Castle.
 *
 * @version $Id: b45c4b63eaa1487cd1610e3ca20d308e982100a1 $
 * @since 6.0M1
 */
@Component
@Singleton
public class DefaultCMSSignedDataVerifier implements CMSSignedDataVerifier, Initializable
{
    @Inject
    private DigestFactory digestProvider;

    @Inject
    private BcContentVerifierProviderBuilder contentVerifierProviderBuilder;

    @Inject
    @Named("X509")
    private CertificateFactory certFactory;

    @Inject
    @Named("X509")
    private CertificateChainBuilder chainBuilder;

    @Inject
    private ComponentManager manager;

    @Override
    public void initialize() throws InitializationException
    {
        if (!(this.digestProvider instanceof DigestCalculatorProvider)) {
            throw new InitializationException("Incompatible DigestFactory for this signed data verifier.");
        }
    }

    @Override
    public CMSSignedDataVerified verify(byte[] signature) throws GeneralSecurityException
    {
        return verify(signature, null, (CertificateProvider) null);
    }

    @Override
    public CMSSignedDataVerified verify(byte[] signature, Collection certificates)
        throws GeneralSecurityException
    {
        return verify(signature, null, certificates);
    }

    @Override
    public CMSSignedDataVerified verify(byte[] signature, CertificateProvider certificateProvider)
        throws GeneralSecurityException
    {
        return verify(signature, null, certificateProvider);
    }

    @Override
    public CMSSignedDataVerified verify(byte[] signature, byte[] data) throws GeneralSecurityException
    {
        return verify(signature, data, (CertificateProvider) null);
    }

    @Override
    public CMSSignedDataVerified verify(byte[] signature, byte[] data,
        Collection certificates) throws GeneralSecurityException
    {
        return verify(signature, data, BcStoreUtils.getCertificateProvider(this.manager, certificates));
    }

    @Override
    public CMSSignedDataVerified verify(byte[] signature, byte[] data, CertificateProvider certificateProvider)
        throws GeneralSecurityException
    {
        CMSSignedData signedData = BcCMSUtils.getSignedData(signature, data);

        CertificateProvider provider = BcStoreUtils.getCertificateProvider(this.manager, signedData.getCertificates(),
            certificateProvider);

        return verify(signedData, provider);
    }

    private CMSSignedDataVerified verify(CMSSignedData signedData, CertificateProvider provider)
    {
        BcCMSSignedDataVerified verifiedData = BcCMSUtils.getCMSSignedDataVerified(signedData, this.certFactory);

        for (SignerInformation signer : BcCMSUtils.getSigners(signedData)) {
            CertifiedPublicKey certKey = BcStoreUtils.getCertificate(provider, signer, this.certFactory);

            try {
                verifiedData.addSignature(
                    new BcCMSSignerVerifiedInformation(signer,
                        BcCMSUtils.verify(signer, certKey, this.contentVerifierProviderBuilder, this.digestProvider),
                        this.chainBuilder.build(certKey, provider)));
            } catch (CMSException e) {
                verifiedData.addSignature(
                    new BcCMSSignerVerifiedInformation(signer, false, this.chainBuilder.build(certKey, provider)));
            }
        }

        return verifiedData;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy