// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.its;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.Signature;
import java.io.OutputStream;
import org.bouncycastle.oer.its.ieee1609dot2.CertificateType;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.HashedId8;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.oer.its.ieee1609dot2.IssuerIdentifier;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.HashAlgorithm;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.oer.its.ieee1609dot2.CertificateBase;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.its.operator.ECDSAEncoder;
import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
import java.io.IOException;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.oer.OEREncoder;
import org.bouncycastle.oer.its.template.ieee1609dot2.IEEE1609dot2;
import org.bouncycastle.oer.its.ieee1609dot2.VerificationKeyIndicator;
import org.bouncycastle.oer.its.ieee1609dot2.CertificateId;
import org.bouncycastle.oer.its.ieee1609dot2.ToBeSignedCertificate;
import org.bouncycastle.its.operator.ITSContentSigner;

public class ITSExplicitCertificateBuilder extends ITSCertificateBuilder
{
    private final ITSContentSigner signer;
    
    public ITSExplicitCertificateBuilder(final ITSContentSigner signer, final ToBeSignedCertificate.Builder builder) {
        super(builder);
        this.signer = signer;
    }
    
    public ITSCertificate build(final CertificateId certificateId, final ITSPublicVerificationKey itsPublicVerificationKey) {
        return this.build(certificateId, itsPublicVerificationKey, null);
    }
    
    public ITSCertificate build(final CertificateId id, final ITSPublicVerificationKey itsPublicVerificationKey, final ITSPublicEncryptionKey itsPublicEncryptionKey) {
        final ToBeSignedCertificate.Builder builder = new ToBeSignedCertificate.Builder(this.tbsCertificateBuilder);
        builder.setId(id);
        if (itsPublicEncryptionKey != null) {
            builder.setEncryptionKey(itsPublicEncryptionKey.toASN1Structure());
        }
        builder.setVerifyKeyIndicator(VerificationKeyIndicator.verificationKey(itsPublicVerificationKey.toASN1Structure()));
        final ToBeSignedCertificate toBeSignedCertificate = builder.createToBeSignedCertificate();
        VerificationKeyIndicator verificationKeyIndicator;
        if (this.signer.isForSelfSigning()) {
            verificationKeyIndicator = toBeSignedCertificate.getVerifyKeyIndicator();
        }
        else {
            verificationKeyIndicator = this.signer.getAssociatedCertificate().toASN1Structure().getToBeSigned().getVerifyKeyIndicator();
        }
        final OutputStream outputStream = this.signer.getOutputStream();
        try {
            outputStream.write(OEREncoder.toByteArray(toBeSignedCertificate, IEEE1609dot2.ToBeSignedCertificate.build()));
            outputStream.close();
        }
        catch (final IOException ex) {
            throw new IllegalArgumentException("cannot produce certificate signature");
        }
        Signature signature = null;
        switch (verificationKeyIndicator.getChoice()) {
            case 0: {
                signature = ECDSAEncoder.toITS(SECObjectIdentifiers.secp256r1, this.signer.getSignature());
                break;
            }
            case 1: {
                signature = ECDSAEncoder.toITS(TeleTrusTObjectIdentifiers.brainpoolP256r1, this.signer.getSignature());
                break;
            }
            case 2: {
                signature = ECDSAEncoder.toITS(TeleTrusTObjectIdentifiers.brainpoolP384r1, this.signer.getSignature());
                break;
            }
            default: {
                throw new IllegalStateException("unknown key type");
            }
        }
        final CertificateBase.Builder builder2 = new CertificateBase.Builder();
        final ASN1ObjectIdentifier algorithm = this.signer.getDigestAlgorithm().getAlgorithm();
        IssuerIdentifier issuer;
        if (this.signer.isForSelfSigning()) {
            if (algorithm.equals(NISTObjectIdentifiers.id_sha256)) {
                issuer = IssuerIdentifier.self(HashAlgorithm.sha256);
            }
            else {
                if (!algorithm.equals(NISTObjectIdentifiers.id_sha384)) {
                    throw new IllegalStateException("unknown digest");
                }
                issuer = IssuerIdentifier.self(HashAlgorithm.sha384);
            }
        }
        else {
            final byte[] associatedCertificateDigest = this.signer.getAssociatedCertificateDigest();
            final HashedId8 hashedId8 = new HashedId8(Arrays.copyOfRange(associatedCertificateDigest, associatedCertificateDigest.length - 8, associatedCertificateDigest.length));
            if (algorithm.equals(NISTObjectIdentifiers.id_sha256)) {
                issuer = IssuerIdentifier.sha256AndDigest(hashedId8);
            }
            else {
                if (!algorithm.equals(NISTObjectIdentifiers.id_sha384)) {
                    throw new IllegalStateException("unknown digest");
                }
                issuer = IssuerIdentifier.sha384AndDigest(hashedId8);
            }
        }
        builder2.setVersion(this.version);
        builder2.setType(CertificateType.explicit);
        builder2.setIssuer(issuer);
        builder2.setToBeSigned(toBeSignedCertificate);
        builder2.setSignature(signature);
        return new ITSCertificate(builder2.createCertificateBase());
    }
}
