use of com.yahoo.athenz.auth.impl.CertificateAuthority in project athenz by yahoo.
the class ZTSImplTest method testPostInstanceRefreshInformationSSHMismatchSerial.
@Test
public void testPostInstanceRefreshInformationSSHMismatchSerial() throws IOException {
ChangeLogStore structStore = new ZMSFileChangeLogStore("/tmp/zts_server_unit_tests/zts_root", privateKey, "0");
DataStore store = new DataStore(structStore, null);
ZTSImpl ztsImpl = new ZTSImpl(mockCloudStore, store);
SignedDomain providerDomain = signedAuthorizedProviderDomain();
store.processDomain(providerDomain, false);
SignedDomain tenantDomain = signedBootstrapTenantDomain("athenz.provider", "athenz", "production");
store.processDomain(tenantDomain, false);
InstanceCertManager instanceManager = Mockito.spy(ztsImpl.instanceCertManager);
X509CertRecord certRecord = new X509CertRecord();
certRecord.setInstanceId("1001");
certRecord.setProvider("athenz.provider");
certRecord.setService("athenz.production");
certRecord.setCurrentSerial("123413");
certRecord.setPrevSerial("123413");
Mockito.when(instanceManager.getX509CertRecord("athenz.provider", "1001")).thenReturn(certRecord);
Mockito.when(instanceManager.updateX509CertRecord(Mockito.any())).thenReturn(true);
ztsImpl.instanceCertManager = instanceManager;
InstanceRefreshInformation info = new InstanceRefreshInformation().setSsh("ssh-csr");
CertificateAuthority certAuthority = new CertificateAuthority();
SimplePrincipal principal = (SimplePrincipal) SimplePrincipal.create("athenz", "production", "v=S1;d=athenz;n=production;s=signature", 0, certAuthority);
Path path = Paths.get("src/test/resources/athenz.instanceid.pem");
String pem = new String(Files.readAllBytes(path));
X509Certificate cert = Crypto.loadX509Certificate(pem);
principal.setX509Certificate(cert);
ResourceContext context = createResourceContext(principal);
try {
ztsImpl.postInstanceRefreshInformation(context, "athenz.provider", "athenz", "production", "1001", info);
fail();
} catch (ResourceException ex) {
assertEquals(ex.getCode(), 403);
}
}
use of com.yahoo.athenz.auth.impl.CertificateAuthority in project athenz by yahoo.
the class ZTSImplTest method testPostOSTKInstanceRefreshRequest.
@Test
public void testPostOSTKInstanceRefreshRequest() throws IOException {
Path path = Paths.get("src/test/resources/athenz.instanceid.csr");
String certCsr = new String(Files.readAllBytes(path));
OSTKInstanceRefreshRequest req = new OSTKInstanceRefreshRequest().setCsr(certCsr);
SimplePrincipal principal = (SimplePrincipal) SimplePrincipal.create("athenz", "production", "v=S1,d=athenz;n=production;s=sig", 0, new CertificateAuthority());
HttpServletRequest servletRequest = Mockito.mock(HttpServletRequest.class);
Mockito.when(servletRequest.isSecure()).thenReturn(true);
path = Paths.get("src/test/resources/athenz.instanceid.pem");
String pem = new String(Files.readAllBytes(path));
X509Certificate cert = Crypto.loadX509Certificate(pem);
principal.setX509Certificate(cert);
ResourceContext context = createResourceContext(principal, servletRequest);
X509CertRecord certRecord = new X509CertRecord();
certRecord.setService("athenz.production");
certRecord.setInstanceId("1001");
certRecord.setCurrentSerial("16503746516960996918");
certRecord.setPrevSerial("16503746516960996918");
CertRecordStore certStore = Mockito.mock(CertRecordStore.class);
CertRecordStoreConnection certConnection = Mockito.mock(CertRecordStoreConnection.class);
Mockito.when(certStore.getConnection()).thenReturn(certConnection);
Mockito.when(certConnection.getX509CertRecord("ostk", "1001")).thenReturn(certRecord);
Mockito.when(certConnection.updateX509CertRecord(ArgumentMatchers.isA(X509CertRecord.class))).thenReturn(true);
zts.instanceCertManager.setCertStore(certStore);
Identity identity = zts.postOSTKInstanceRefreshRequest(context, "athenz", "production", req);
assertNotNull(identity);
X509Certificate x509Cert = Crypto.loadX509Certificate(identity.getCertificate());
assertNotNull(x509Cert);
}
use of com.yahoo.athenz.auth.impl.CertificateAuthority 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 com.yahoo.athenz.auth.impl.CertificateAuthority in project athenz by yahoo.
the class ZTSImpl method postInstanceRefreshInformation.
@Override
public InstanceIdentity postInstanceRefreshInformation(ResourceContext ctx, String provider, String domain, String service, String instanceId, InstanceRefreshInformation info) {
final String caller = "postinstancerefreshinformation";
final String callerTiming = "postinstancerefreshinformation_timing";
metric.increment(HTTP_POST);
logPrincipal(ctx);
validateRequest(ctx.request(), caller);
validate(provider, TYPE_SERVICE_NAME, caller);
validate(domain, TYPE_DOMAIN_NAME, caller);
validate(service, TYPE_SIMPLE_NAME, caller);
validate(instanceId, TYPE_PATH_ELEMENT, caller);
validate(info, TYPE_INSTANCE_REFRESH_INFO, 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)
provider = provider.toLowerCase();
domain = domain.toLowerCase();
service = service.toLowerCase();
Object timerMetric = metric.startTiming(callerTiming, domain);
metric.increment(HTTP_REQUEST, domain);
metric.increment(caller, domain);
// before running any checks make sure it's coming from
// an authorized ip address
final String ipAddress = ServletRequestUtil.getRemoteAddress(ctx.request());
if (!instanceCertManager.verifyInstanceCertIPAddress(ipAddress)) {
throw forbiddenError("Unknown IP: " + ipAddress, caller, domain);
}
// we are going to get two use cases here. client asking for:
// * x509 cert (optionally with ssh certificate)
// * only ssh certificate
// both CSRs are marked as optional so we need to make sure
// at least one of the CSRs is provided
final String x509Csr = convertEmptyStringToNull(info.getCsr());
final String sshCsr = convertEmptyStringToNull(info.getSsh());
if (x509Csr == null && sshCsr == null) {
throw requestError("no csr provided", caller, domain);
}
// make sure the credentials match to whatever the request is
Principal principal = ((RsrcCtxWrapper) ctx).principal();
final String principalName = domain + "." + service;
if (!principalName.equals(principal.getFullName())) {
throw requestError("Principal mismatch: " + principalName + " vs. " + principal.getFullName(), caller, domain);
}
Authority authority = principal.getAuthority();
if (!(authority instanceof CertificateAuthority)) {
throw requestError("Unsupported authority for TLS Certs: " + authority.toString(), caller, domain);
}
// first we need to make sure that the provider has been
// authorized in Athenz to bootstrap/launch instances
Principal providerService = createPrincipalForName(provider);
StringBuilder errorMsg = new StringBuilder(256);
if (!instanceCertManager.authorizeLaunch(providerService, domain, service, authorizer, errorMsg)) {
throw forbiddenError(errorMsg.toString(), caller, domain);
}
// extract our instance certificate record to make sure it
// hasn't been revoked already
X509CertRecord x509CertRecord = instanceCertManager.getX509CertRecord(provider, instanceId);
if (x509CertRecord == null) {
throw forbiddenError("Unable to find certificate record", caller, domain);
}
if (!principalName.equals(x509CertRecord.getService())) {
throw requestError("service name mismatch - csr: " + principalName + " cert db: " + x509CertRecord.getService(), caller, domain);
}
InstanceIdentity identity = null;
if (x509Csr != null) {
identity = processProviderX509RefreshRequest(ctx, principal, domain, service, provider, providerService, instanceId, info, x509CertRecord, caller);
} else {
identity = processProviderSSHRefreshRequest(ctx, principal, domain, service, provider, instanceId, sshCsr, x509CertRecord, caller);
}
metric.stopTiming(timerMetric);
return identity;
}
use of com.yahoo.athenz.auth.impl.CertificateAuthority in project athenz by yahoo.
the class ZTSImplTest method testPostInstanceRefreshInformationCertDNSMismatch.
@Test
public void testPostInstanceRefreshInformationCertDNSMismatch() throws IOException {
ChangeLogStore structStore = new ZMSFileChangeLogStore("/tmp/zts_server_unit_tests/zts_root", privateKey, "0");
DataStore store = new DataStore(structStore, null);
ZTSImpl ztsImpl = new ZTSImpl(mockCloudStore, store);
SignedDomain providerDomain = signedAuthorizedProviderDomain();
store.processDomain(providerDomain, false);
SignedDomain tenantDomain = signedBootstrapTenantDomain("athenz.provider", "athenz", "production");
store.processDomain(tenantDomain, false);
Path path = Paths.get("src/test/resources/athenz.instanceid.csr");
String certCsr = new String(Files.readAllBytes(path));
InstanceProviderManager instanceProviderManager = Mockito.mock(InstanceProviderManager.class);
InstanceProvider providerClient = Mockito.mock(InstanceProvider.class);
InstanceConfirmation confirmation = new InstanceConfirmation().setDomain("athenz").setService("production").setProvider("athenz.provider");
InstanceCertManager instanceManager = Mockito.spy(ztsImpl.instanceCertManager);
X509CertRecord certRecord = new X509CertRecord();
certRecord.setInstanceId("1001");
certRecord.setProvider("athenz.provider");
certRecord.setService("athenz.production");
certRecord.setCurrentSerial("16503746516960996918");
certRecord.setPrevSerial("16503746516960996918");
Mockito.when(instanceManager.getX509CertRecord("athenz.provider", "1001")).thenReturn(certRecord);
Mockito.when(instanceProviderManager.getProvider("athenz.provider")).thenReturn(providerClient);
Mockito.when(providerClient.refreshInstance(Mockito.any())).thenReturn(confirmation);
path = Paths.get("src/test/resources/valid_cn_x509.cert");
String pem = new String(Files.readAllBytes(path));
InstanceIdentity identity = new InstanceIdentity().setName("athenz.production").setX509Certificate(pem);
Mockito.doReturn(identity).when(instanceManager).generateIdentity(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyInt());
ztsImpl.instanceProviderManager = instanceProviderManager;
ztsImpl.instanceCertManager = instanceManager;
InstanceRefreshInformation info = new InstanceRefreshInformation().setCsr(certCsr);
CertificateAuthority certAuthority = new CertificateAuthority();
SimplePrincipal principal = (SimplePrincipal) SimplePrincipal.create("athenz", "production", "v=S1;d=athenz;n=production;s=signature", 0, certAuthority);
X509Certificate cert = Crypto.loadX509Certificate(pem);
principal.setX509Certificate(cert);
ResourceContext context = createResourceContext(principal);
try {
ztsImpl.postInstanceRefreshInformation(context, "athenz.provider", "athenz", "production", "1001", info);
fail();
} catch (ResourceException ex) {
assertEquals(ex.getCode(), 400);
assertTrue(ex.getMessage().contains("dnsName attribute mismatch in CSR"));
}
}
Aggregations