ZTSImpl implements KeyStore, ZTSHandler { @Deprecated @Override public Identity postOSTKInstanceRefreshRequest(ResourceContext ctx, String domain, String service, OSTKInstanceRefreshRequest req) { final String caller = ctx.getApiName(); final String principalDomain = logPrincipalAndGetDomain(ctx); if (readOnlyMode) { throw requestError("Server in Maintenance Read-Only mode. Please try your request later", caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN, principalDomain); } validateRequest(ctx.request(), principalDomain, caller); validate(domain, TYPE_DOMAIN_NAME, principalDomain, caller); validate(service, TYPE_SIMPLE_NAME, principalDomain, caller); validate(req, TYPE_OSTK_INSTANCE_REFRESH_REQUEST, principalDomain, caller); domain = domain.toLowerCase(); setRequestDomain(ctx, domain); service = service.toLowerCase(); 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, principalDomain); } Authority authority = principal.getAuthority(); if (!(authority instanceof CertificateAuthority)) { throw requestError("postOSTKInstanceRefreshRequest: Unsupported authority for TLS Certs: " + authority.toString(), caller, domain, principalDomain); } X509Certificate cert = principal.getX509Certificate(); X509CertRecord x509CertRecord = instanceCertManager.getX509CertRecord("ostk", cert); if (x509CertRecord == null) { throw forbiddenError("postOSTKInstanceRefreshRequest: Unable to find certificate record", caller, domain, principalDomain); } PKCS10CertificationRequest certReq = Crypto.getPKCS10CertRequest(req.getCsr()); if (certReq == null) { throw requestError("postOSTKInstanceRefreshRequest: unable to parse PKCS10 certificate request", caller, domain, principalDomain); } if (!ZTSUtils.verifyCertificateRequest(certReq, domain, service, x509CertRecord)) { throw requestError("postOSTKInstanceRefreshRequest: invalid CSR - cn mismatch", caller, domain, principalDomain); } String serialNumber = cert.getSerialNumber().toString(); if (x509CertRecord.getCurrentSerial().equals(serialNumber)) { x509CertRecord.setPrevIP(x509CertRecord.getCurrentIP()); x509CertRecord.setPrevTime(x509CertRecord.getCurrentTime()); x509CertRecord.setPrevSerial(x509CertRecord.getCurrentSerial()); } else if (!x509CertRecord.getPrevSerial().equals(serialNumber)) { 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, principalDomain); } Identity identity = ZTSUtils.generateIdentity(instanceCertManager, req.getCsr(), principalName, null, 0); if (identity == null) { throw serverError("Unable to generate identity", caller, domain, principalDomain); } identity.setCaCertBundle(instanceCertManager.getX509CertificateSigner()); final String ipAddress = ServletRequestUtil.getRemoteAddress(ctx.request()); X509Certificate newCert = Crypto.loadX509Certificate(identity.getCertificate()); x509CertRecord.setCurrentSerial(newCert.getSerialNumber().toString()); x509CertRecord.setCurrentIP(ipAddress); x509CertRecord.setCurrentTime(new Date()); if (!instanceCertManager.updateX509CertRecord(x509CertRecord)) { throw serverError("postOSTKInstanceRefreshRequest: unable to update cert db", caller, domain, principalDomain); } instanceCertManager.logX509Cert(principal, ipAddress, "ostk", x509CertRecord.getInstanceId(), newCert); return identity; } ZTSImpl();  ZTSImpl(CloudStore implCloudStore, DataStore implDataStore); @Override String getPublicKey(String domain, String service, String keyId); ServiceIdentity getServiceIdentity(ResourceContext ctx, String domainName, String serviceName); PublicKeyEntry getPublicKeyEntry(ResourceContext ctx, String domainName,
            String serviceName, String keyId); ServiceIdentityList getServiceIdentityList(ResourceContext ctx, String domainName); HostServices getHostServices(ResourceContext ctx, String host); Response getDomainSignedPolicyData(ResourceContext ctx, String domainName, String matchingTag); TenantDomains getTenantDomains(ResourceContext ctx, String providerDomainName,
            String userName, String roleName, String serviceName); @Override RoleToken getRoleToken(ResourceContext ctx, String domainName, String roleNames,
            Integer minExpiryTime, Integer maxExpiryTime, String proxyForPrincipal); @Override AccessTokenResponse postAccessTokenRequest(ResourceContext ctx, String request); RoleAccess getRoleAccess(ResourceContext ctx, String domainName, String principal); @Override RoleToken postRoleCertificateRequest(ResourceContext ctx, String domainName,
            String roleName, RoleCertificateRequest req); @Override RoleCertificate postRoleCertificateRequestExt(ResourceContext ctx, RoleCertificateRequest req); AWSTemporaryCredentials getAWSTemporaryCredentials(ResourceContext ctx, String domainName,
            String roleName, Integer durationSeconds, String externalId); @Override Response postInstanceRegisterInformation(ResourceContext ctx, InstanceRegisterInformation info); @Override InstanceIdentity postInstanceRefreshInformation(ResourceContext ctx, String provider,
            String domain, String service, String instanceId, InstanceRefreshInformation info); @Override void deleteInstanceIdentity(ResourceContext ctx, String provider,
            String domain, String service, String instanceId); @Deprecated @Override Identity postInstanceRefreshRequest(ResourceContext ctx, String domain,
            String service, InstanceRefreshRequest req); @Override Response postSSHCertRequest(ResourceContext ctx, SSHCertRequest certRequest); @Override JWKList getJWKList(ResourceContext ctx, Boolean rfc); @Deprecated @Override Identity postOSTKInstanceRefreshRequest(ResourceContext ctx, String domain,
            String service, OSTKInstanceRefreshRequest req); @Override ResourceAccess getResourceAccessExt(ResourceContext ctx, String action, String resource,
            String trustDomain, String checkPrincipal); @Override ResourceAccess getResourceAccess(ResourceContext ctx, String action, String resource,
            String trustDomain, String checkPrincipal); @Override Access getAccess(ResourceContext ctx, String domainName, String roleName,
            String principal); CertificateAuthorityBundle getCertificateAuthorityBundle(ResourceContext ctx, String name); @Override DomainMetrics postDomainMetrics(ResourceContext ctx, String domainName,
            DomainMetrics domainMetrics); @Override Status getStatus(ResourceContext ctx); @Override Schema getRdlSchema(ResourceContext context); ResourceContext newResourceContext(HttpServletRequest request,
                                              HttpServletResponse response,
                                              String apiName); static String getRootDir(); void recordMetrics(ResourceContext ctx, int httpStatus);  }
@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", "athenz.production")).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); }
@Test public void testPostOSTKInstanceRefreshRequestPreviousSerialMatch() 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.setProvider("ostk"); certRecord.setInstanceId("1001"); certRecord.setCurrentSerial("12341324334"); 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", "athenz.production")).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); }
@Test public void testPostOSTKInstanceRefreshRequestSerialMisMatch() 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.setProvider("ostk"); certRecord.setInstanceId("1001"); certRecord.setCurrentSerial("12341324334"); certRecord.setPrevSerial("2342134323"); CertRecordStore certStore = Mockito.mock(CertRecordStore.class); CertRecordStoreConnection certConnection = Mockito.mock(CertRecordStoreConnection.class); Mockito.when(certStore.getConnection()).thenReturn(certConnection); Mockito.when(certConnection.getX509CertRecord("ostk", "1001", "athenz.production")).thenReturn(certRecord); Mockito.when(certConnection.updateX509CertRecord(ArgumentMatchers.isA(X509CertRecord.class))).thenReturn(true); zts.instanceCertManager.setCertStore(certStore); try { zts.postOSTKInstanceRefreshRequest(context, "athenz", "production", req); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 403); assertTrue(ex.getMessage().contains("Certificate revoked")); } }
@Test public void testPostOSTKInstanceRefreshRequestCertRecordCnMismatch() 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("athenz2.production"); certRecord.setProvider("ostk"); CertRecordStore certStore = Mockito.mock(CertRecordStore.class); CertRecordStoreConnection certConnection = Mockito.mock(CertRecordStoreConnection.class); Mockito.when(certStore.getConnection()).thenReturn(certConnection); Mockito.when(certConnection.getX509CertRecord("ostk", "1001", "athenz.production")).thenReturn(certRecord); zts.instanceCertManager.setCertStore(certStore); try { zts.postOSTKInstanceRefreshRequest(context, "athenz", "production", req); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 400); assertTrue(ex.getMessage().contains("cn mismatch")); } }
@Test public void testPostOSTKInstanceRefreshRequestPrincipalMismatch() 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( "athenz2", "production", "v=S1,d=athenz2;n=production;s=sig", 0, new CertificateAuthority() ); HttpServletRequest servletRequest = Mockito.mock(HttpServletRequest.class); Mockito.when(servletRequest.isSecure()).thenReturn(true); ResourceContext context = createResourceContext(principal, servletRequest); try { zts.postOSTKInstanceRefreshRequest(context, "athenz", "production", req); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 400); } }