// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.security;

import org.junit.Test;

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;

import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;

/**
 * @author bjorncs
 */
public class KeyUtilsTest {

    @Test
    public void can_extract_public_key_from_rsa_private() {
        KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA);
        PublicKey publicKey = KeyUtils.extractPublicKey(keyPair.getPrivate());
        assertNotNull(publicKey);
    }

    @Test
    public void can_extract_public_key_from_ecdsa_private() {
        KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.EC);
        PublicKey publicKey = KeyUtils.extractPublicKey(keyPair.getPrivate());
        assertNotNull(publicKey);
    }

    @Test
    public void can_serialize_and_deserialize_rsa_privatekey_using_pkcs1_pem_format() {
        KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA);
        String pem = KeyUtils.toPem(keyPair.getPrivate(), KeyFormat.PKCS1);
        assertThat(pem, containsString("BEGIN RSA PRIVATE KEY"));
        assertThat(pem, containsString("END RSA PRIVATE KEY"));
        PrivateKey deserializedKey = KeyUtils.fromPemEncodedPrivateKey(pem);
        assertEquals(keyPair.getPrivate(), deserializedKey);
        assertEquals(KeyAlgorithm.RSA.getAlgorithmName(), deserializedKey.getAlgorithm());
    }

    @Test
    public void can_serialize_and_deserialize_rsa_privatekey_using_pkcs8_pem_format() {
        KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA);
        String pem = KeyUtils.toPem(keyPair.getPrivate(), KeyFormat.PKCS8);
        assertThat(pem, containsString("BEGIN PRIVATE KEY"));
        assertThat(pem, containsString("END PRIVATE KEY"));
        PrivateKey deserializedKey = KeyUtils.fromPemEncodedPrivateKey(pem);
        assertEquals(keyPair.getPrivate(), deserializedKey);
        assertEquals(KeyAlgorithm.RSA.getAlgorithmName(), deserializedKey.getAlgorithm());
    }

    @Test
    public void can_serialize_and_deserialize_ec_privatekey_using_pkcs1_pem_format() {
        KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.EC);
        String pem = KeyUtils.toPem(keyPair.getPrivate(), KeyFormat.PKCS1);
        assertThat(pem, containsString("BEGIN EC PRIVATE KEY"));
        assertThat(pem, containsString("END EC PRIVATE KEY"));
        PrivateKey deserializedKey = KeyUtils.fromPemEncodedPrivateKey(pem);
        assertEquals(keyPair.getPrivate(), deserializedKey);
        assertEquals(KeyAlgorithm.EC.getAlgorithmName(), deserializedKey.getAlgorithm());
    }

    @Test
    public void can_serialize_and_deserialize_ec_privatekey_using_pkcs8_pem_format() {
        KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.EC);
        String pem = KeyUtils.toPem(keyPair.getPrivate(), KeyFormat.PKCS8);
        assertThat(pem, containsString("BEGIN PRIVATE KEY"));
        assertThat(pem, containsString("END PRIVATE KEY"));
        PrivateKey deserializedKey = KeyUtils.fromPemEncodedPrivateKey(pem);
        assertEquals(keyPair.getPrivate(), deserializedKey);
        assertEquals(KeyAlgorithm.EC.getAlgorithmName(), deserializedKey.getAlgorithm());
    }

    @Test
    public void can_serialize_and_deserialize_rsa_publickey_using_pem_format() {
        KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA);
        String pem = KeyUtils.toPem(keyPair.getPublic());
        assertThat(pem, containsString("BEGIN PUBLIC KEY"));
        assertThat(pem, containsString("END PUBLIC KEY"));
        PublicKey deserializedKey = KeyUtils.fromPemEncodedPublicKey(pem);
        assertEquals(keyPair.getPublic(), deserializedKey);
        assertEquals(KeyAlgorithm.RSA.getAlgorithmName(), deserializedKey.getAlgorithm());
    }

    @Test
    public void can_serialize_and_deserialize_ec_publickey_using_pem_format() {
        KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.EC);
        String pem = KeyUtils.toPem(keyPair.getPublic());
        assertThat(pem, containsString("BEGIN PUBLIC KEY"));
        assertThat(pem, containsString("END PUBLIC KEY"));
        PublicKey deserializedKey = KeyUtils.fromPemEncodedPublicKey(pem);
        assertEquals(keyPair.getPublic(), deserializedKey);
        assertEquals(KeyAlgorithm.EC.getAlgorithmName(), deserializedKey.getAlgorithm());
    }

}

@@ -1139,2308 +1139,663 @@
     
-KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA);%0A        String pem = KeyUtils.toPem(keyPair.getPrivate(), KeyFormat.PKCS1);%0A        assertThat(pem, containsString(%22BEGIN RSA PRIVATE KEY%22));%0A        assertThat(pem, containsString(%22END RSA PRIVATE KEY%22));%0A        PrivateKey deserializedKey = KeyUtils.fromPemEncodedPrivateKey(pem);%0A        assertEquals(keyPair.getPrivate(), deserializedKey);%0A        assertEquals(KeyAlgorithm.RSA.getAlgorithmName(), deserializedKey.getAlgorithm());%0A    %7D%0A%0A    @Test%0A    public void can_serialize_and_deserialize_rsa_privatekey_using_pkcs8_pem_format() %7B%0A        KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA);%0A        String pem = KeyUtils.toPem(keyPair.getPrivate(), KeyFormat.PKCS8);%0A        assertThat(pem, containsString(%22BEGIN PRIVATE KEY%22));%0A        assertThat(pem, containsString(%22END PRIVATE KEY%22));%0A        PrivateKey deserializedKey = KeyUtils.fromPemEncodedPrivateKey(pem);%0A        assertEquals(keyPair.getPrivate(), deserializedKey);%0A        assertEquals(KeyAlgorithm.RSA.getAlgorithmName(), deserializedKey.getAlgorithm());%0A    %7D%0A%0A    @Test%0A    public void can_serialize_and_deserialize_ec_privatekey_using_pkcs1_pem_format() %7B%0A        KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.EC);%0A        String pem = KeyUtils.toPem(keyPair.getPrivate(), KeyFormat.PKCS1);%0A        assertThat(pem, containsString(%22BEGIN EC PRIVATE KEY%22));%0A        assertThat(pem, containsString(%22END EC PRIVATE KEY%22));%0A        PrivateKey deserializedKey = KeyUtils.fromPemEncodedPrivateKey(pem);%0A        assertEquals(keyPair.getPrivate(), deserializedKey);%0A        assertEquals(KeyAlgorithm.EC.getAlgorithmName(), deserializedKey.getAlgorithm());%0A    %7D%0A%0A    @Test%0A    public void can_serialize_and_deserialize_ec_privatekey_using_pkcs8_pem_format() %7B%0A        KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.EC);%0A        String pem = KeyUtils.toPem(keyPair.getPrivate(), KeyFormat.PKCS8);%0A        assertThat(pem, containsString(%22BEGIN PRIVATE KEY%22));%0A        assertThat(pem, containsString(%22END PRIVATE KEY%22));%0A        PrivateKey deserializedKey = KeyUtils.fromPemEncodedPrivateKey(pem);%0A        assertEquals(keyPair.getPrivate(), deserializedKey);%0A        assertEquals(KeyAlgorithm.EC.getAlgorithmName(), deserializedKey.getAlgorithm()
+testPrivateKeySerialization(KeyAlgorithm.RSA, KeyFormat.PKCS1, %22RSA PRIVATE KEY%22);%0A    %7D%0A%0A    @Test%0A    public void can_serialize_and_deserialize_rsa_privatekey_using_pkcs8_pem_format() %7B%0A        testPrivateKeySerialization(KeyAlgorithm.RSA, KeyFormat.PKCS8, %22PRIVATE KEY%22);%0A    %7D%0A%0A    @Test%0A    public void can_serialize_and_deserialize_ec_privatekey_using_pkcs1_pem_format() %7B%0A        testPrivateKeySerialization(KeyAlgorithm.EC, KeyFormat.PKCS1, %22EC PRIVATE KEY%22);%0A    %7D%0A%0A    @Test%0A    public void can_serialize_and_deserialize_ec_privatekey_using_pkcs8_pem_format() %7B%0A        testPrivateKeySerialization(KeyAlgorithm.EC, KeyFormat.PKCS8, %22PRIVATE KEY%22
 );%0A 
@@ -2941,10 +2941,619 @@
 %0A    %7D%0A%0A
+    private static void testPrivateKeySerialization(KeyAlgorithm keyAlgorithm, KeyFormat keyFormat, String pemLabel) %7B%0A        KeyPair keyPair = KeyUtils.generateKeypair(keyAlgorithm);%0A        String pem = KeyUtils.toPem(keyPair.getPrivate(), keyFormat);%0A        assertThat(pem, containsString(%22BEGIN %22 + pemLabel));%0A        assertThat(pem, containsString(%22END %22 + pemLabel));%0A        PrivateKey deserializedKey = KeyUtils.fromPemEncodedPrivateKey(pem);%0A        assertEquals(keyPair.getPrivate(), deserializedKey);%0A        assertEquals(keyAlgorithm.getAlgorithmName(), deserializedKey.getAlgorithm());%0A    %7D%0A%0A
 %7D%0A

Refactor private key serialization tests