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();
}
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));
}
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);
}
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;
}
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"));
}
Aggregations