Search in sources :

Example 1 with PKCS10CertificationRequest

use of org.bouncycastle.pkcs.PKCS10CertificationRequest in project curiostack by curioswitch.

the class RequestNamespaceCertTask method exec.

@TaskAction
public void exec() {
    ImmutableClusterExtension cluster = getProject().getExtensions().getByType(ClusterExtension.class);
    final KeyPairGenerator keygen;
    try {
        keygen = KeyPairGenerator.getInstance("ECDSA", BouncyCastleProvider.PROVIDER_NAME);
    } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
        throw new IllegalStateException("Could not find RSA, can't happen.", e);
    }
    keygen.initialize(256, new SecureRandom());
    KeyPair keyPair = keygen.generateKeyPair();
    PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(new X500Principal("CN=" + cluster.namespace() + ".ns.cluster.stellarstation.com"), keyPair.getPublic());
    Stream<GeneralName> generalNames = Streams.concat(Stream.of(new GeneralName(GeneralName.dNSName, "*." + cluster.namespace()), new GeneralName(GeneralName.dNSName, "*." + cluster.namespace() + ".svc"), new GeneralName(GeneralName.dNSName, "*." + cluster.namespace() + ".svc.cluster.local")), cluster.extraNamespaceTlsHosts().stream().map(name -> new GeneralName(GeneralName.dNSName, name)));
    GeneralNames subjectAltNames = new GeneralNames(generalNames.toArray(GeneralName[]::new));
    ExtensionsGenerator extensions = new ExtensionsGenerator();
    try {
        extensions.addExtension(Extension.subjectAlternativeName, false, subjectAltNames);
        p10Builder.setAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extensions.generate());
    } catch (IOException e) {
        throw new IllegalStateException("Could not encode cert name, can't happen.", e);
    }
    final ContentSigner signer;
    try {
        signer = new JcaContentSignerBuilder("SHA256withECDSA").build(keyPair.getPrivate());
    } catch (OperatorCreationException e) {
        throw new IllegalStateException("Could not find signer, can't happen.", e);
    }
    PKCS10CertificationRequest csr = p10Builder.build(signer);
    StringWriter csrWriter = new StringWriter();
    try (JcaPEMWriter pemWriter = new JcaPEMWriter(csrWriter)) {
        pemWriter.writeObject(csr);
    } catch (IOException e) {
        throw new IllegalStateException("Could not encode csr, can't happen.", e);
    }
    String encodedCsr = Base64.getEncoder().encodeToString(csrWriter.toString().getBytes(StandardCharsets.UTF_8));
    Map<Object, Object> csrApiRequest = ImmutableMap.of("apiVersion", "certificates.k8s.io/v1beta1", "kind", "CertificateSigningRequest", "metadata", ImmutableMap.of("name", cluster.namespace() + ".server.crt"), "spec", ImmutableMap.of("request", encodedCsr, "usages", ImmutableList.of("digital signature", "key encipherment", "server auth", "client auth")));
    final byte[] encodedApiRequest;
    try {
        encodedApiRequest = OBJECT_MAPPER.writeValueAsBytes(csrApiRequest);
    } catch (JsonProcessingException e) {
        throw new IllegalStateException("Could not encode yaml", e);
    }
    ImmutableGcloudExtension config = getProject().getRootProject().getExtensions().getByType(GcloudExtension.class);
    String command = config.download() ? CommandUtil.getGcloudSdkBinDir(getProject()).resolve("kubectl").toAbsolutePath().toString() : "kubectl";
    getProject().exec(exec -> {
        exec.executable(command);
        exec.args("create", "-f", "-");
        exec.setStandardInput(new ByteArrayInputStream(encodedApiRequest));
    });
    getProject().exec(exec -> {
        exec.executable(command);
        exec.args("certificate", "approve", cluster.namespace() + ".server.crt");
    });
    // Need to wait a bit for certificate to propagate before fetching.
    try {
        TimeUnit.SECONDS.sleep(5);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    // Gradle Exec seems to be flaky when reading from stdout, so use normal ProcessBuilder.
    final byte[] certificateBytes;
    try {
        Process getCertProcess = new ProcessBuilder(command, "get", "csr", cluster.namespace() + ".server.crt", "-o", "jsonpath={.status.certificate}").start();
        certificateBytes = ByteStreams.toByteArray(getCertProcess.getInputStream());
    } catch (IOException e) {
        throw new UncheckedIOException("Could not fetch certificate.", e);
    }
    String certificate = new String(Base64.getDecoder().decode(certificateBytes), StandardCharsets.UTF_8);
    final JcaPKCS8Generator keyGenerator;
    final PemObject keyObject;
    try {
        keyGenerator = new JcaPKCS8Generator(keyPair.getPrivate(), null);
        keyObject = keyGenerator.generate();
    } catch (PemGenerationException e) {
        throw new IllegalStateException("Could not encode to pkcs8.", e);
    }
    StringWriter keyWriter = new StringWriter();
    try (JcaPEMWriter pemWriter = new JcaPEMWriter(keyWriter)) {
        pemWriter.writeObject(keyObject);
    } catch (IOException e) {
        throw new IllegalStateException("Could not encode csr, can't happen.", e);
    }
    String key = keyWriter.toString();
    KubernetesClient client = new DefaultKubernetesClient();
    Secret certificateSecret = new SecretBuilder().withMetadata(new ObjectMetaBuilder().withName("server-tls").withNamespace(cluster.namespace()).build()).withType("Opaque").withData(ImmutableMap.of("server.crt", Base64.getEncoder().encodeToString(certificate.getBytes(StandardCharsets.UTF_8)), "server-key.pem", Base64.getEncoder().encodeToString(key.getBytes(StandardCharsets.UTF_8)))).build();
    client.resource(certificateSecret).createOrReplace();
}
Also used : KeyPair(java.security.KeyPair) PKCS10CertificationRequest(org.bouncycastle.pkcs.PKCS10CertificationRequest) Extension(org.bouncycastle.asn1.x509.Extension) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) Security(java.security.Security) SecureRandom(java.security.SecureRandom) TaskAction(org.gradle.api.tasks.TaskAction) ByteArrayInputStream(java.io.ByteArrayInputStream) Map(java.util.Map) PemGenerationException(org.bouncycastle.util.io.pem.PemGenerationException) PKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder) DefaultTask(org.gradle.api.DefaultTask) DefaultKubernetesClient(io.fabric8.kubernetes.client.DefaultKubernetesClient) KeyPairGenerator(java.security.KeyPairGenerator) PemObject(org.bouncycastle.util.io.pem.PemObject) ImmutableMap(com.google.common.collect.ImmutableMap) Streams(com.google.common.collect.Streams) StandardCharsets(java.nio.charset.StandardCharsets) UncheckedIOException(java.io.UncheckedIOException) Base64(java.util.Base64) GeneralName(org.bouncycastle.asn1.x509.GeneralName) Stream(java.util.stream.Stream) GcloudExtension(org.curioswitch.gradle.plugins.gcloud.GcloudExtension) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ByteStreams(com.google.common.io.ByteStreams) Secret(io.fabric8.kubernetes.api.model.Secret) JcaPEMWriter(org.bouncycastle.openssl.jcajce.JcaPEMWriter) X500Principal(javax.security.auth.x500.X500Principal) PKCSObjectIdentifiers(org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers) ContentSigner(org.bouncycastle.operator.ContentSigner) ImmutableGcloudExtension(org.curioswitch.gradle.plugins.gcloud.ImmutableGcloudExtension) JcaContentSignerBuilder(org.bouncycastle.operator.jcajce.JcaContentSignerBuilder) ImmutableClusterExtension(org.curioswitch.gradle.plugins.gcloud.ImmutableClusterExtension) ImmutableList(com.google.common.collect.ImmutableList) ClusterExtension(org.curioswitch.gradle.plugins.gcloud.ClusterExtension) YAMLFactory(com.fasterxml.jackson.dataformat.yaml.YAMLFactory) ExtensionsGenerator(org.bouncycastle.asn1.x509.ExtensionsGenerator) ObjectMetaBuilder(io.fabric8.kubernetes.api.model.ObjectMetaBuilder) JcaPKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder) StringWriter(java.io.StringWriter) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) IOException(java.io.IOException) BouncyCastleProvider(org.bouncycastle.jce.provider.BouncyCastleProvider) TimeUnit(java.util.concurrent.TimeUnit) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) CommandUtil(org.curioswitch.gradle.plugins.shared.CommandUtil) SecretBuilder(io.fabric8.kubernetes.api.model.SecretBuilder) JcaPKCS8Generator(org.bouncycastle.openssl.jcajce.JcaPKCS8Generator) NoSuchProviderException(java.security.NoSuchProviderException) ImmutableGcloudExtension(org.curioswitch.gradle.plugins.gcloud.ImmutableGcloudExtension) JcaContentSignerBuilder(org.bouncycastle.operator.jcajce.JcaContentSignerBuilder) UncheckedIOException(java.io.UncheckedIOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ImmutableClusterExtension(org.curioswitch.gradle.plugins.gcloud.ImmutableClusterExtension) SecretBuilder(io.fabric8.kubernetes.api.model.SecretBuilder) StringWriter(java.io.StringWriter) JcaPKCS8Generator(org.bouncycastle.openssl.jcajce.JcaPKCS8Generator) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) PKCS10CertificationRequest(org.bouncycastle.pkcs.PKCS10CertificationRequest) KeyPair(java.security.KeyPair) DefaultKubernetesClient(io.fabric8.kubernetes.client.DefaultKubernetesClient) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) JcaPKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder) PemGenerationException(org.bouncycastle.util.io.pem.PemGenerationException) ContentSigner(org.bouncycastle.operator.ContentSigner) SecureRandom(java.security.SecureRandom) PKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder) JcaPKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder) KeyPairGenerator(java.security.KeyPairGenerator) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) ObjectMetaBuilder(io.fabric8.kubernetes.api.model.ObjectMetaBuilder) ExtensionsGenerator(org.bouncycastle.asn1.x509.ExtensionsGenerator) Secret(io.fabric8.kubernetes.api.model.Secret) PemObject(org.bouncycastle.util.io.pem.PemObject) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) ByteArrayInputStream(java.io.ByteArrayInputStream) X500Principal(javax.security.auth.x500.X500Principal) PemObject(org.bouncycastle.util.io.pem.PemObject) GeneralName(org.bouncycastle.asn1.x509.GeneralName) DefaultKubernetesClient(io.fabric8.kubernetes.client.DefaultKubernetesClient) NoSuchProviderException(java.security.NoSuchProviderException) JcaPEMWriter(org.bouncycastle.openssl.jcajce.JcaPEMWriter) TaskAction(org.gradle.api.tasks.TaskAction)

Example 2 with PKCS10CertificationRequest

use of org.bouncycastle.pkcs.PKCS10CertificationRequest in project athenz by yahoo.

the class CryptoTest method testExtractCsrFieldsNoRfc822.

@Test
public void testExtractCsrFieldsNoRfc822() throws IOException {
    Path path = Paths.get("src/test/resources/valid.csr");
    String csr = new String(Files.readAllBytes(path));
    PKCS10CertificationRequest certReq = Crypto.getPKCS10CertRequest(csr);
    assertEquals(Crypto.extractX509CSRCommonName(certReq), "athenz.syncer");
    assertNull(Crypto.extractX509CSREmail(certReq));
}
Also used : Path(java.nio.file.Path) PKCS10CertificationRequest(org.bouncycastle.pkcs.PKCS10CertificationRequest) DERIA5String(org.bouncycastle.asn1.DERIA5String) Test(org.testng.annotations.Test)

Example 3 with PKCS10CertificationRequest

use of org.bouncycastle.pkcs.PKCS10CertificationRequest in project athenz by yahoo.

the class SelfCertSigner method generateX509Certificate.

@Override
public String generateX509Certificate(String csr, String keyUsage, int expiryTime) {
    int certExpiryTime = expiryTime == 0 ? certValidityTime : expiryTime;
    PKCS10CertificationRequest certReq = Crypto.getPKCS10CertRequest(csr);
    X509Certificate cert = Crypto.generateX509Certificate(certReq, caPrivateKey, caCertificate, certExpiryTime, false);
    return Crypto.convertToPEMFormat(cert);
}
Also used : PKCS10CertificationRequest(org.bouncycastle.pkcs.PKCS10CertificationRequest) X509Certificate(java.security.cert.X509Certificate)

Example 4 with PKCS10CertificationRequest

use of org.bouncycastle.pkcs.PKCS10CertificationRequest in project athenz by yahoo.

the class ZTSImpl method postOSTKInstanceRefreshRequest.

// this method will be removed and replaced with call to postInstanceRefreshInformation
@Override
public Identity postOSTKInstanceRefreshRequest(ResourceContext ctx, String domain, String service, OSTKInstanceRefreshRequest req) {
    final String caller = "postostkinstancerefreshrequest";
    final String callerTiming = "postostkinstancerefreshrequest_timing";
    metric.increment(HTTP_POST);
    logPrincipal(ctx);
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("postOSTKInstanceRefreshRequest: " + req);
    }
    validateRequest(ctx.request(), caller);
    validate(domain, TYPE_DOMAIN_NAME, caller);
    validate(service, TYPE_SIMPLE_NAME, caller);
    validate(req, TYPE_OSTK_INSTANCE_REFRESH_REQUEST, caller);
    // for consistent handling of all requests, we're going to convert
    // all incoming object values into lower case (e.g. domain, role,
    // policy, service, etc name)
    domain = domain.toLowerCase();
    service = service.toLowerCase();
    Object timerMetric = metric.startTiming(callerTiming, domain);
    metric.increment(HTTP_REQUEST, domain);
    metric.increment(caller, domain);
    // make sure the credentials match to whatever the request is
    Principal principal = ((RsrcCtxWrapper) ctx).principal();
    String principalName = domain + "." + service;
    if (!principalName.equals(principal.getFullName())) {
        throw requestError("postOSTKInstanceRefreshRequest: Principal mismatch: " + principalName + " vs. " + principal.getFullName(), caller, domain);
    }
    Authority authority = principal.getAuthority();
    if (!(authority instanceof CertificateAuthority)) {
        throw requestError("postOSTKInstanceRefreshRequest: Unsupported authority for TLS Certs: " + authority.toString(), caller, domain);
    }
    X509Certificate cert = principal.getX509Certificate();
    X509CertRecord x509CertRecord = instanceCertManager.getX509CertRecord("ostk", cert);
    if (x509CertRecord == null) {
        throw forbiddenError("postOSTKInstanceRefreshRequest: Unable to find certificate record", caller, domain);
    }
    // validate that the cn and public key (if required) match to
    // the provided details
    PKCS10CertificationRequest certReq = Crypto.getPKCS10CertRequest(req.getCsr());
    if (certReq == null) {
        throw requestError("postOSTKInstanceRefreshRequest: unable to parse PKCS10 certificate request", caller, domain);
    }
    if (!ZTSUtils.verifyCertificateRequest(certReq, domain, service, x509CertRecord)) {
        throw requestError("postOSTKInstanceRefreshRequest: invalid CSR - cn mismatch", caller, domain);
    }
    // now we need to make sure the serial number for the certificate
    // matches to what we had issued previously. If we have a mismatch
    // then we're going to revoke this instance as it has been possibly
    // compromised
    String serialNumber = cert.getSerialNumber().toString();
    if (x509CertRecord.getCurrentSerial().equals(serialNumber)) {
        // update the record to mark current as previous
        // and we'll update the current set with our existing
        // details
        x509CertRecord.setPrevIP(x509CertRecord.getCurrentIP());
        x509CertRecord.setPrevTime(x509CertRecord.getCurrentTime());
        x509CertRecord.setPrevSerial(x509CertRecord.getCurrentSerial());
    } else if (!x509CertRecord.getPrevSerial().equals(serialNumber)) {
        // we have a mismatch for both current and previous serial
        // numbers so we're going to revoke it
        LOGGER.error("postOSTKInstanceRefreshRequest: Revoking certificate refresh for cn: {} " + "instance id: {}, current serial: {}, previous serial: {}, cert serial: {}", principalName, x509CertRecord.getInstanceId(), x509CertRecord.getCurrentSerial(), x509CertRecord.getPrevSerial(), serialNumber);
        x509CertRecord.setPrevSerial("-1");
        x509CertRecord.setCurrentSerial("-1");
        instanceCertManager.updateX509CertRecord(x509CertRecord);
        throw forbiddenError("postOSTKInstanceRefreshRequest: Certificate revoked", caller, domain);
    }
    // generate identity with the certificate
    Identity identity = ZTSUtils.generateIdentity(certSigner, req.getCsr(), principalName, null, 0);
    if (identity == null) {
        throw serverError("Unable to generate identity", caller, domain);
    }
    // need to update our cert record with new certificate details
    X509Certificate newCert = Crypto.loadX509Certificate(identity.getCertificate());
    x509CertRecord.setCurrentSerial(newCert.getSerialNumber().toString());
    x509CertRecord.setCurrentIP(ServletRequestUtil.getRemoteAddress(ctx.request()));
    x509CertRecord.setCurrentTime(new Date());
    if (!instanceCertManager.updateX509CertRecord(x509CertRecord)) {
        throw serverError("postOSTKInstanceRefreshRequest: unable to update cert db", caller, domain);
    }
    metric.stopTiming(timerMetric);
    return identity;
}
Also used : PKCS10CertificationRequest(org.bouncycastle.pkcs.PKCS10CertificationRequest) Authority(com.yahoo.athenz.auth.Authority) CertificateAuthority(com.yahoo.athenz.auth.impl.CertificateAuthority) CertificateAuthority(com.yahoo.athenz.auth.impl.CertificateAuthority) SimplePrincipal(com.yahoo.athenz.auth.impl.SimplePrincipal) Principal(com.yahoo.athenz.auth.Principal) X509Certificate(java.security.cert.X509Certificate) X509CertRecord(com.yahoo.athenz.zts.cert.X509CertRecord) Date(java.util.Date)

Example 5 with PKCS10CertificationRequest

use of org.bouncycastle.pkcs.PKCS10CertificationRequest in project athenz by yahoo.

the class X509CertRequestTest method testComparePublicKeysFailure.

@Test
public void testComparePublicKeysFailure() throws IOException {
    Path path = Paths.get("src/test/resources/athenz.instanceid.csr");
    String csr = new String(Files.readAllBytes(path));
    X509CertRequest certReq = new X509CertRequest(csr);
    assertNotNull(certReq);
    PKCS10CertificationRequest req = Mockito.mock(PKCS10CertificationRequest.class);
    Mockito.when(req.getSubjectPublicKeyInfo()).thenReturn(null);
    certReq.setCertReq(req);
    assertFalse(certReq.comparePublicKeys("publickey"));
}
Also used : Path(java.nio.file.Path) PKCS10CertificationRequest(org.bouncycastle.pkcs.PKCS10CertificationRequest) Test(org.testng.annotations.Test)

Aggregations

PKCS10CertificationRequest (org.bouncycastle.pkcs.PKCS10CertificationRequest)79 Test (org.testng.annotations.Test)39 Path (java.nio.file.Path)34 DERIA5String (org.bouncycastle.asn1.DERIA5String)19 X509Certificate (java.security.cert.X509Certificate)17 IOException (java.io.IOException)14 X500Name (org.bouncycastle.asn1.x500.X500Name)13 PrivateKey (java.security.PrivateKey)12 JcaContentSignerBuilder (org.bouncycastle.operator.jcajce.JcaContentSignerBuilder)11 JcaPKCS10CertificationRequestBuilder (org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder)11 KeyPair (java.security.KeyPair)9 X500Principal (javax.security.auth.x500.X500Principal)9 KeyPairGenerator (java.security.KeyPairGenerator)8 ContentSigner (org.bouncycastle.operator.ContentSigner)8 OperatorCreationException (org.bouncycastle.operator.OperatorCreationException)8 File (java.io.File)7 BouncyCastleProvider (org.bouncycastle.jce.provider.BouncyCastleProvider)7 JcaPKCS10CertificationRequest (org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest)7 PemObject (org.bouncycastle.util.io.pem.PemObject)6 CryptoException (org.kse.crypto.CryptoException)6