okhttp3.tls.HeldCertificateTest.java Source code

Java tutorial

Introduction

Here is the source code for okhttp3.tls.HeldCertificateTest.java

Source

/*
 * Copyright (C) 2018 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package okhttp3.tls;

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import okio.ByteString;
import org.bouncycastle.asn1.x509.GeneralName;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

public final class HeldCertificateTest {
    @Test
    public void defaultCertificate() throws CertificateParsingException {
        long now = System.currentTimeMillis();
        HeldCertificate heldCertificate = new HeldCertificate.Builder().build();

        X509Certificate certificate = heldCertificate.certificate();
        assertEquals("self-signed", certificate.getIssuerX500Principal().getName(),
                certificate.getSubjectX500Principal().getName());
        assertTrue(certificate.getIssuerX500Principal().getName().matches("CN=[0-9a-f-]{36}"));
        assertEquals(BigInteger.ONE, certificate.getSerialNumber());
        assertNull(certificate.getSubjectAlternativeNames());

        double deltaMillis = 1000.0;
        long durationMillis = TimeUnit.MINUTES.toMillis(60 * 24);
        assertEquals((double) now, certificate.getNotBefore().getTime(), deltaMillis);
        assertEquals((double) now + durationMillis, certificate.getNotAfter().getTime(), deltaMillis);
    }

    @Test
    public void customInterval() {
        // 5 seconds starting on 1970-01-01.
        HeldCertificate heldCertificate = new HeldCertificate.Builder().validityInterval(5_000L, 10_000L).build();
        X509Certificate certificate = heldCertificate.certificate();
        assertEquals(5_000L, certificate.getNotBefore().getTime());
        assertEquals(10_000L, certificate.getNotAfter().getTime());
    }

    @Test
    public void customDuration() {
        long now = System.currentTimeMillis();

        HeldCertificate heldCertificate = new HeldCertificate.Builder().duration(5, TimeUnit.SECONDS).build();
        X509Certificate certificate = heldCertificate.certificate();

        double deltaMillis = 1000.0;
        long durationMillis = 5_000L;
        assertEquals((double) now, certificate.getNotBefore().getTime(), deltaMillis);
        assertEquals((double) now + durationMillis, certificate.getNotAfter().getTime(), deltaMillis);
    }

    @Test
    public void subjectAlternativeNames() throws CertificateParsingException {
        HeldCertificate heldCertificate = new HeldCertificate.Builder().addSubjectAlternativeName("1.1.1.1")
                .addSubjectAlternativeName("cash.app").build();

        X509Certificate certificate = heldCertificate.certificate();
        List<List<?>> subjectAlternativeNames = new ArrayList<>(certificate.getSubjectAlternativeNames());
        assertEquals(subjectAlternativeNames, Arrays.asList(Arrays.asList(GeneralName.iPAddress, "1.1.1.1"),
                Arrays.asList(GeneralName.dNSName, "cash.app")));
    }

    @Test
    public void commonName() {
        HeldCertificate heldCertificate = new HeldCertificate.Builder().commonName("cash.app").build();

        X509Certificate certificate = heldCertificate.certificate();
        assertEquals("CN=cash.app", certificate.getSubjectX500Principal().getName());
    }

    @Test
    public void organizationalUnit() {
        HeldCertificate heldCertificate = new HeldCertificate.Builder().commonName("cash.app")
                .organizationalUnit("cash").build();

        X509Certificate certificate = heldCertificate.certificate();
        assertEquals("CN=cash.app,OU=cash", certificate.getSubjectX500Principal().getName());
    }

    /** Confirm golden values of encoded PEMs. */
    @Test
    public void pems() throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        ByteString publicKeyBytes = ByteString.decodeBase64("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCApF"
                + "HhtrLan28q+oMolZuaTfWBA0V5aMIvq32BsloQu6LlvX1wJ4YEoUCjDlPOtpht7XLbUmBnbIzN89XK4UJVM6Sqp3"
                + "K88Km8z7gMrdrfTom/274wL25fICR+yDEQ5fUVYBmJAKXZF1aoI0mIoEx0xFsQhIJ637v2MxJDupd61wIDAQAB");
        PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyBytes.toByteArray()));

        ByteString privateKeyBytes = ByteString.decodeBase64("MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbA"
                + "gEAAoGBAICkUeG2stqfbyr6gyiVm5pN9YEDRXlowi+rfYGyWhC7ouW9fXAnhgShQKMOU862mG3tcttSYGdsjM3z1"
                + "crhQlUzpKqncrzwqbzPuAyt2t9Oib/bvjAvbl8gJH7IMRDl9RVgGYkApdkXVqgjSYigTHTEWxCEgnrfu/YzEkO6l"
                + "3rXAgMBAAECgYB99mhnB6piADOuddXv626NzUBTr4xbsYRTgSxHzwf50oFTTBSDuW+1IOBVyTWu94SSPyt0LllPb"
                + "C8Di3sQSTnVGpSqAvEXknBMzIc0UO74Rn9p3gZjEenPt1l77fIBa2nK06/rdsJCoE/1P1JSfM9w7LU1RsTmseYML"
                + "eJl5F79gQJBAO/BbAKqg1yzK7VijygvBoUrr+rt2lbmKgcUQ/rxu8IIQk0M/xgJqSkXDXuOnboGM7sQSKfJAZUtT"
                + "7xozvLzV7ECQQCJW59w7NIM0qZ/gIX2gcNZr1B/V3zcGlolTDciRm+fnKGNt2EEDKnVL3swzbEfTCa48IT0QKgZJ"
                + "qpXZERa26UHAkBLXmiP5f5pk8F3wcXzAeVw06z3k1IB41Tu6MX+CyPU+TeudRlz+wV8b0zDvK+EnRKCCbptVFj1B"
                + "kt8lQ4JfcnhAkAk2Y3Gz+HySrkcT7Cg12M/NkdUQnZe3jr88pt/+IGNwomc6Wt/mJ4fcWONTkGMcfOZff1NQeNXD"
                + "AZ6941XCsIVAkASOg02PlVHLidU7mIE65swMM5/RNhS4aFjez/MwxFNOHaxc9VgCwYPXCLOtdf7AVovdyG0XWgbU"
                + "XH+NyxKwboE");
        PrivateKey privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes.toByteArray()));

        HeldCertificate heldCertificate = new HeldCertificate.Builder().keyPair(publicKey, privateKey)
                .commonName("cash.app").validityInterval(0L, 1_000L).rsa2048().build();

        assertEquals(heldCertificate.certificatePem(),
                "" + "-----BEGIN CERTIFICATE-----\n"
                        + "MIIBmjCCAQOgAwIBAgIBATANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDEwhjYXNo\n"
                        + "LmFwcDAeFw03MDAxMDEwMDAwMDBaFw03MDAxMDEwMDAwMDFaMBMxETAPBgNVBAMT\n"
                        + "CGNhc2guYXBwMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCApFHhtrLan28q\n"
                        + "+oMolZuaTfWBA0V5aMIvq32BsloQu6LlvX1wJ4YEoUCjDlPOtpht7XLbUmBnbIzN\n"
                        + "89XK4UJVM6Sqp3K88Km8z7gMrdrfTom/274wL25fICR+yDEQ5fUVYBmJAKXZF1ao\n"
                        + "I0mIoEx0xFsQhIJ637v2MxJDupd61wIDAQABMA0GCSqGSIb3DQEBCwUAA4GBADam\n"
                        + "UVwKh5Ry7es3OxtY3IgQunPUoLc0Gw71gl9Z+7t2FJ5VkcI5gWfutmdxZ2bDXCI8\n"
                        + "8V0vxo1pHXnbBrnxhS/Z3TBerw8RyQqcaWOdp+pBXyIWmR+jHk9cHZCqQveTIBsY\n"
                        + "jaA9VEhgdaVhxBsT2qzUNDsXlOzGsliznDfoqETb\n" + "-----END CERTIFICATE-----\n");

        assertEquals(heldCertificate.privateKeyPkcs1Pem(),
                "" + "-----BEGIN RSA PRIVATE KEY-----\n"
                        + "MIICWwIBAAKBgQCApFHhtrLan28q+oMolZuaTfWBA0V5aMIvq32BsloQu6LlvX1w\n"
                        + "J4YEoUCjDlPOtpht7XLbUmBnbIzN89XK4UJVM6Sqp3K88Km8z7gMrdrfTom/274w\n"
                        + "L25fICR+yDEQ5fUVYBmJAKXZF1aoI0mIoEx0xFsQhIJ637v2MxJDupd61wIDAQAB\n"
                        + "AoGAffZoZweqYgAzrnXV7+tujc1AU6+MW7GEU4EsR88H+dKBU0wUg7lvtSDgVck1\n"
                        + "rveEkj8rdC5ZT2wvA4t7EEk51RqUqgLxF5JwTMyHNFDu+EZ/ad4GYxHpz7dZe+3y\n"
                        + "AWtpytOv63bCQqBP9T9SUnzPcOy1NUbE5rHmDC3iZeRe/YECQQDvwWwCqoNcsyu1\n"
                        + "Yo8oLwaFK6/q7dpW5ioHFEP68bvCCEJNDP8YCakpFw17jp26BjO7EEinyQGVLU+8\n"
                        + "aM7y81exAkEAiVufcOzSDNKmf4CF9oHDWa9Qf1d83BpaJUw3IkZvn5yhjbdhBAyp\n"
                        + "1S97MM2xH0wmuPCE9ECoGSaqV2REWtulBwJAS15oj+X+aZPBd8HF8wHlcNOs95NS\n"
                        + "AeNU7ujF/gsj1Pk3rnUZc/sFfG9Mw7yvhJ0Sggm6bVRY9QZLfJUOCX3J4QJAJNmN\n"
                        + "xs/h8kq5HE+woNdjPzZHVEJ2Xt46/PKbf/iBjcKJnOlrf5ieH3FjjU5BjHHzmX39\n"
                        + "TUHjVwwGeveNVwrCFQJAEjoNNj5VRy4nVO5iBOubMDDOf0TYUuGhY3s/zMMRTTh2\n"
                        + "sXPVYAsGD1wizrXX+wFaL3chtF1oG1Fx/jcsSsG6BA==\n" + "-----END RSA PRIVATE KEY-----\n");

        assertEquals(heldCertificate.privateKeyPkcs8Pem(),
                "" + "-----BEGIN PRIVATE KEY-----\n"
                        + "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAICkUeG2stqfbyr6\n"
                        + "gyiVm5pN9YEDRXlowi+rfYGyWhC7ouW9fXAnhgShQKMOU862mG3tcttSYGdsjM3z\n"
                        + "1crhQlUzpKqncrzwqbzPuAyt2t9Oib/bvjAvbl8gJH7IMRDl9RVgGYkApdkXVqgj\n"
                        + "SYigTHTEWxCEgnrfu/YzEkO6l3rXAgMBAAECgYB99mhnB6piADOuddXv626NzUBT\n"
                        + "r4xbsYRTgSxHzwf50oFTTBSDuW+1IOBVyTWu94SSPyt0LllPbC8Di3sQSTnVGpSq\n"
                        + "AvEXknBMzIc0UO74Rn9p3gZjEenPt1l77fIBa2nK06/rdsJCoE/1P1JSfM9w7LU1\n"
                        + "RsTmseYMLeJl5F79gQJBAO/BbAKqg1yzK7VijygvBoUrr+rt2lbmKgcUQ/rxu8II\n"
                        + "Qk0M/xgJqSkXDXuOnboGM7sQSKfJAZUtT7xozvLzV7ECQQCJW59w7NIM0qZ/gIX2\n"
                        + "gcNZr1B/V3zcGlolTDciRm+fnKGNt2EEDKnVL3swzbEfTCa48IT0QKgZJqpXZERa\n"
                        + "26UHAkBLXmiP5f5pk8F3wcXzAeVw06z3k1IB41Tu6MX+CyPU+TeudRlz+wV8b0zD\n"
                        + "vK+EnRKCCbptVFj1Bkt8lQ4JfcnhAkAk2Y3Gz+HySrkcT7Cg12M/NkdUQnZe3jr8\n"
                        + "8pt/+IGNwomc6Wt/mJ4fcWONTkGMcfOZff1NQeNXDAZ6941XCsIVAkASOg02PlVH\n"
                        + "LidU7mIE65swMM5/RNhS4aFjez/MwxFNOHaxc9VgCwYPXCLOtdf7AVovdyG0XWgb\n" + "UXH+NyxKwboE\n"
                        + "-----END PRIVATE KEY-----\n");
    }

    @Test
    public void ecdsaSignedByRsa() {
        HeldCertificate root = new HeldCertificate.Builder().certificateAuthority(0).rsa2048().build();
        HeldCertificate leaf = new HeldCertificate.Builder().certificateAuthority(0).ecdsa256().signedBy(root)
                .build();

        assertEquals("SHA256WITHRSA", root.certificate().getSigAlgName());
        assertEquals("SHA256WITHRSA", leaf.certificate().getSigAlgName());
    }

    @Test
    public void rsaSignedByEcdsa() {
        HeldCertificate root = new HeldCertificate.Builder().certificateAuthority(0).ecdsa256().build();
        HeldCertificate leaf = new HeldCertificate.Builder().certificateAuthority(0).rsa2048().signedBy(root)
                .build();

        assertEquals("SHA256WITHECDSA", root.certificate().getSigAlgName());
        assertEquals("SHA256WITHECDSA", leaf.certificate().getSigAlgName());
    }
}