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

com.amazonaws.encryptionsdk.internal.TrailingSignatureAlgorithm Maven / Gradle / Ivy

package com.amazonaws.encryptionsdk.internal;

import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;

import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.interfaces.ECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.math.ec.ECPoint;

import java.util.Base64;

import com.amazonaws.encryptionsdk.CryptoAlgorithm;

/**
 * Provides a consistent interface across various trailing signature algorithms.
 *
 * NOTE: This is not a stable API and may undergo breaking changes in the future.
 */
public abstract class TrailingSignatureAlgorithm {
    private TrailingSignatureAlgorithm() {
        /* Do not allow arbitrary subclasses */
    }

    public abstract String getMessageDigestAlgorithm();
    public abstract String getRawSignatureAlgorithm();
    public abstract String getHashAndSignAlgorithm();
    public abstract PublicKey deserializePublicKey(String keyString);
    public abstract String serializePublicKey(PublicKey key);
    public abstract KeyPair generateKey() throws GeneralSecurityException;

    private static final class ECDSASignatureAlgorithm extends TrailingSignatureAlgorithm {
        private final ECNamedCurveParameterSpec ecSpec;
        private final String messageDigestAlgorithm;
        private final String hashAndSignAlgorithm;

        private ECDSASignatureAlgorithm(ECNamedCurveParameterSpec ecSpec, String messageDigestAlgorithm) {
            this.ecSpec = ecSpec;
            this.messageDigestAlgorithm = messageDigestAlgorithm;
            this.hashAndSignAlgorithm = messageDigestAlgorithm + "withECDSA";
        }

        @Override
        public String toString() {
            return "ECDSASignatureAlgorithm(curve=" + ecSpec.getName() + ")";
        }

        @Override
        public String getMessageDigestAlgorithm() {
            return messageDigestAlgorithm;
        }

        @Override
        public String getRawSignatureAlgorithm() {
            return "NONEwithECDSA";
        }

        @Override public String getHashAndSignAlgorithm() {
            return hashAndSignAlgorithm;
        }

        @Override
        public PublicKey deserializePublicKey(String keyString) {
            final ECPoint q = ecSpec.getCurve().decodePoint(Base64.getDecoder().decode(keyString));

            ECPublicKeyParameters keyParams = new ECPublicKeyParameters(
                    q,
                    new ECDomainParameters(ecSpec.getCurve(), ecSpec.getG(), ecSpec.getN(), ecSpec.getH())
            );

            return new BCECPublicKey("ECDSA", keyParams, ecSpec, BouncyCastleProvider.CONFIGURATION);
        }

        @Override
        public String serializePublicKey(PublicKey key) {
            return Base64.getEncoder().encodeToString(((ECPublicKey)key).getQ().getEncoded(true));
        }

        @Override
        public KeyPair generateKey() throws GeneralSecurityException {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA", "BC");
            keyGen.initialize(ecSpec, Utils.getSecureRandom());

            return keyGen.generateKeyPair();
        }
    }

    private static final ECDSASignatureAlgorithm SHA256_ECDSA_P256
            = new ECDSASignatureAlgorithm(ECNamedCurveTable.getParameterSpec("secp256r1"), "SHA256");
    private static final ECDSASignatureAlgorithm SHA384_ECDSA_P384
            = new ECDSASignatureAlgorithm(ECNamedCurveTable.getParameterSpec("secp384r1"), "SHA384");

    public static TrailingSignatureAlgorithm forCryptoAlgorithm(CryptoAlgorithm algorithm) {
        switch (algorithm) {
            case ALG_AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256:
                return SHA256_ECDSA_P256;
            case ALG_AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384:
            case ALG_AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384:
                return SHA384_ECDSA_P384;
            default:
                throw new IllegalStateException("Algorithm does not support trailing signature");
        }
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy