ZTSImpl implements KeyStore, ZTSHandler { @Override public RoleCertificate postRoleCertificateRequestExt(ResourceContext ctx, RoleCertificateRequest 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(req, TYPE_ROLE_CERTIFICATE_REQUEST, principalDomain, caller); final Principal principal = ((RsrcCtxWrapper) ctx).principal(); validatePrincipalNotRoleIdentity(principal, caller); String proxyForPrincipal = req.getProxyForPrincipal(); if (proxyForPrincipal != null) { proxyForPrincipal = normalizeDomainAliasUser(proxyForPrincipal.toLowerCase()); } final String domainName = principal.getDomain(); setRequestDomain(ctx, principalDomain); if (isAuthorizedServicePrincipal(principal)) { throw forbiddenError("Authorized Service Principals not allowed", caller, domainName, domainName); } String principalName = principal.getFullName(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("postRoleCertificateRequestExt(principal: {}, proxy-for: {}", principalName, proxyForPrincipal); } if (proxyForPrincipal != null && !isAuthorizedProxyUser(authorizedProxyUsers, principalName)) { LOGGER.error("postRoleCertificateRequestExt: Principal: " + principalName + " not authorized for proxy role certificate request"); throw forbiddenError("postRoleCertificateRequestExt: Principal: " + principalName + " not authorized for proxy role certificate request", caller, domainName, domainName); } X509RoleCertRequest certReq; try { certReq = new X509RoleCertRequest(req.getCsr()); } catch (CryptoException ex) { throw requestError("Unable to parse PKCS10 CSR: " + ex.getMessage(), caller, domainName, domainName); } Map<String, String[]> requestedRoleList = certReq.getRequestedRoleList(); if (requestedRoleList == null) { throw requestError("No roles requested in CSR", caller, domainName, domainName); } if (singleDomainInRoleCert && requestedRoleList.size() != 1) { throw requestError("Role Certificate cannot contain roles from multiple domains", caller, domainName, domainName); } if (!verifyAccessToRoles(principalName, requestedRoleList)) { throw forbiddenError("Not authorized to assume all requested roles by user principal", caller, domainName, domainName); } String proxyUser = null; if (proxyForPrincipal != null) { if (!verifyAccessToRoles(proxyForPrincipal, requestedRoleList)) { throw forbiddenError("Not authorized to assume all requested roles by proxy principal", caller, domainName, domainName); } proxyUser = principalName; principalName = proxyForPrincipal; } X509Certificate cert = principal.getX509Certificate(); final String ipAddress = ServletRequestUtil.getRemoteAddress(ctx.request()); if (!validateRoleCertificateExtRequest(certReq, principalName, proxyUser, cert, ipAddress)) { throw requestError("postRoleCertificateRequestExt: Unable to validate cert request", caller, domainName, domainName); } int expiryTime = determineRoleCertTimeout(requestedRoleList, (int) req.getExpiryTime()); final String x509Cert = instanceCertManager.generateX509Certificate(req.getCsr(), InstanceProvider.ZTS_CERT_USAGE_CLIENT, expiryTime); if (null == x509Cert || x509Cert.isEmpty()) { throw serverError("postRoleCertificateRequest: Unable to create certificate from the cert signer", caller, domainName, domainName); } RoleCertificate roleCertificate = new RoleCertificate().setX509Certificate(x509Cert); instanceCertManager.logX509Cert(principal, ipAddress, ZTSConsts.ZTS_SERVICE, null, Crypto.loadX509Certificate(x509Cert)); return roleCertificate; } 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 testPostRoleCertificateExtRequest() throws IOException { Path path = Paths.get("src/test/resources/athenz_coretech_role_uri.csr"); String csr = new String(Files.readAllBytes(path)); RoleCertificateRequest req = new RoleCertificateRequest() .setCsr(csr).setExpiryTime(3600L); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); CloudStore cloudStore = new MockCloudStore(); store.setCloudStore(cloudStore); zts.cloudStore = cloudStore; Principal principal = SimplePrincipal.create("user_domain", "user1", "v=U1;d=user_domain;n=user;s=signature", 0, null); ResourceContext context = createResourceContext(principal); RoleCertificate roleCertificate = zts.postRoleCertificateRequestExt(context, req); assertNotNull(roleCertificate); }
@Test public void testPostRoleCertificateExtProxyUserRequest() throws IOException { Path path = Paths.get("src/test/resources/athenz_coretech_proxy_role_uri.csr"); String csr = new String(Files.readAllBytes(path)); RoleCertificateRequest req = new RoleCertificateRequest() .setCsr(csr).setExpiryTime(3600L) .setProxyForPrincipal("user_domain.user1"); List<RoleMember> writers = new ArrayList<>(); writers.add(new RoleMember().setMemberName("user_domain.proxy-user1")); writers.add(new RoleMember().setMemberName("user_domain.user1")); List<RoleMember> readers = new ArrayList<>(); readers.add(new RoleMember().setMemberName("user_domain.proxy-user1")); readers.add(new RoleMember().setMemberName("user_domain.user4")); readers.add(new RoleMember().setMemberName("user_domain.user1")); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", writers, readers, true); store.processDomain(signedDomain, false); CloudStore cloudStore = new MockCloudStore(); store.setCloudStore(cloudStore); zts.cloudStore = cloudStore; Principal principal = SimplePrincipal.create("user_domain", "proxy-user1", "v=U1;d=user_domain;n=proxy-user1;s=signature", 0, null); ResourceContext context = createResourceContext(principal); RoleCertificate roleCertificate = zts.postRoleCertificateRequestExt(context, req); assertNotNull(roleCertificate); }
@Test public void testPostRoleCertificateExtInvalidProxyUserRequest() throws IOException { Path path = Paths.get("src/test/resources/athenz_coretech_proxy_role_uri.csr"); String csr = new String(Files.readAllBytes(path)); RoleCertificateRequest req = new RoleCertificateRequest() .setCsr(csr).setExpiryTime(3600L) .setProxyForPrincipal("user_domain.user1"); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); CloudStore cloudStore = new MockCloudStore(); store.setCloudStore(cloudStore); zts.cloudStore = cloudStore; Principal principal = SimplePrincipal.create("user_domain", "proxy-user100", "v=U1;d=user_domain;n=proxy-user100;s=signature", 0, null); ResourceContext context = createResourceContext(principal); try { zts.postRoleCertificateRequestExt(context, req); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 403); } }
@Test public void testPostRoleCertificateExtAuthzService() throws IOException { Path path = Paths.get("src/test/resources/athenz_coretech_proxy_role_uri.csr"); String csr = new String(Files.readAllBytes(path)); RoleCertificateRequest req = new RoleCertificateRequest() .setCsr(csr).setExpiryTime(3600L); CloudStore cloudStore = new MockCloudStore(); store.setCloudStore(cloudStore); zts.cloudStore = cloudStore; Principal principal = SimplePrincipal.create("user_domain", "user1", "v=U1;d=user_domain;n=user1;s=signature", 0, null); ((SimplePrincipal) principal).setAuthorizedService("sports.hockey.api"); ResourceContext context = createResourceContext(principal); try { zts.postRoleCertificateRequestExt(context, req); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 403); assertTrue(ex.getMessage().contains("Authorized Service Principals not allowed")); } }
@Test public void testPostRoleCertificateExtInvalidCSR() { RoleCertificateRequest req = new RoleCertificateRequest() .setCsr("invalid-csr").setExpiryTime(3600L); CloudStore cloudStore = new MockCloudStore(); store.setCloudStore(cloudStore); zts.cloudStore = cloudStore; Principal principal = SimplePrincipal.create("user_domain", "user1", "v=U1;d=user_domain;n=user1;s=signature", 0, null); ResourceContext context = createResourceContext(principal); try { zts.postRoleCertificateRequestExt(context, req); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 400); assertTrue(ex.getMessage().contains("Unable to parse PKCS10 CSR")); } }
@Test public void testPostRoleCertificateExtNoRoleURI() throws IOException { Path path = Paths.get("src/test/resources/role_single_ip.csr"); String csr = new String(Files.readAllBytes(path)); RoleCertificateRequest req = new RoleCertificateRequest() .setCsr(csr).setExpiryTime(3600L); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); CloudStore cloudStore = new MockCloudStore(); store.setCloudStore(cloudStore); zts.cloudStore = cloudStore; Principal principal = SimplePrincipal.create("user_domain", "user1", "v=U1;d=user_domain;n=user1;s=signature", 0, null); ResourceContext context = createResourceContext(principal); try { zts.postRoleCertificateRequestExt(context, req); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 400); assertTrue(ex.getMessage().contains("No roles requested in CSR")); } }
@Test public void testPostRoleCertificateExtSingleRoleOnly() throws IOException { Path path = Paths.get("src/test/resources/athenz_role_uri.csr"); String csr = new String(Files.readAllBytes(path)); RoleCertificateRequest req = new RoleCertificateRequest() .setCsr(csr).setExpiryTime(3600L); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); CloudStore cloudStore = new MockCloudStore(); store.setCloudStore(cloudStore); zts.cloudStore = cloudStore; Principal principal = SimplePrincipal.create("user_domain", "user1", "v=U1;d=user_domain;n=user;s=signature", 0, null); ResourceContext context = createResourceContext(principal); zts.singleDomainInRoleCert = true; try { zts.postRoleCertificateRequestExt(context, req); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 400); assertTrue(ex.getMessage().contains("cannot contain roles from multiple domains")); } }
@Test public void testPostRoleCertificateExtUserAccessForbidden() throws IOException { Path path = Paths.get("src/test/resources/athenz_coretech_proxy_role_uri.csr"); String csr = new String(Files.readAllBytes(path)); RoleCertificateRequest req = new RoleCertificateRequest() .setCsr(csr).setExpiryTime(3600L) .setProxyForPrincipal("user_domain.user1"); List<RoleMember> writers = new ArrayList<>(); writers.add(new RoleMember().setMemberName("user_domain.proxy-user1")); writers.add(new RoleMember().setMemberName("user_domain.user1")); List<RoleMember> readers = new ArrayList<>(); readers.add(new RoleMember().setMemberName("user_domain.proxy-user1")); readers.add(new RoleMember().setMemberName("user_domain.user4")); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", writers, readers, true); store.processDomain(signedDomain, false); CloudStore cloudStore = new MockCloudStore(); store.setCloudStore(cloudStore); zts.cloudStore = cloudStore; Principal principal = SimplePrincipal.create("user_domain", "proxy-user1", "v=U1;d=user_domain;n=proxy-user1;s=signature", 0, null); ResourceContext context = createResourceContext(principal); try { zts.postRoleCertificateRequestExt(context, req); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 403); assertTrue(ex.getMessage().contains("Not authorized to assume all requested roles by proxy principal")); } }
@Test public void testPostRoleCertificateExtProxyAccessForbidden() throws IOException { Path path = Paths.get("src/test/resources/athenz_coretech_proxy_role_uri.csr"); String csr = new String(Files.readAllBytes(path)); RoleCertificateRequest req = new RoleCertificateRequest() .setCsr(csr).setExpiryTime(3600L) .setProxyForPrincipal("user_domain.user1"); List<RoleMember> writers = new ArrayList<>(); writers.add(new RoleMember().setMemberName("user_domain.proxy-user1")); writers.add(new RoleMember().setMemberName("user_domain.user1")); List<RoleMember> readers = new ArrayList<>(); readers.add(new RoleMember().setMemberName("user_domain.user4")); readers.add(new RoleMember().setMemberName("user_domain.user1")); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", writers, readers, true); store.processDomain(signedDomain, false); CloudStore cloudStore = new MockCloudStore(); store.setCloudStore(cloudStore); zts.cloudStore = cloudStore; Principal principal = SimplePrincipal.create("user_domain", "proxy-user1", "v=U1;d=user_domain;n=proxy-user1;s=signature", 0, null); ResourceContext context = createResourceContext(principal); try { zts.postRoleCertificateRequestExt(context, req); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 403); assertTrue(ex.getMessage().contains("Not authorized to assume all requested roles by user principal")); } }
@Test public void testPostRoleCertificateExtValidateFailed() throws IOException { Path path = Paths.get("src/test/resources/athenz_coretech_proxy_role_uri.csr"); String csr = new String(Files.readAllBytes(path)); RoleCertificateRequest req = new RoleCertificateRequest() .setCsr(csr).setExpiryTime(3600L) .setProxyForPrincipal("user_domain.user1"); List<RoleMember> writers = new ArrayList<>(); writers.add(new RoleMember().setMemberName("user_domain.proxy-user2")); writers.add(new RoleMember().setMemberName("user_domain.user1")); List<RoleMember> readers = new ArrayList<>(); readers.add(new RoleMember().setMemberName("user_domain.proxy-user2")); readers.add(new RoleMember().setMemberName("user_domain.user4")); readers.add(new RoleMember().setMemberName("user_domain.user1")); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", writers, readers, true); store.processDomain(signedDomain, false); CloudStore cloudStore = new MockCloudStore(); store.setCloudStore(cloudStore); zts.cloudStore = cloudStore; Principal principal = SimplePrincipal.create("user_domain", "proxy-user2", "v=U1;d=user_domain;n=proxy-user2;s=signature", 0, null); ResourceContext context = createResourceContext(principal); try { zts.postRoleCertificateRequestExt(context, req); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 400); assertTrue(ex.getMessage().contains("Unable to validate cert request")); } }
@Test public void testPostRoleCertificateExtRequestNullCertReturn() throws IOException { Path path = Paths.get("src/test/resources/athenz_coretech_role_uri.csr"); String csr = new String(Files.readAllBytes(path)); RoleCertificateRequest req = new RoleCertificateRequest() .setCsr(csr).setExpiryTime(3600L); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); CloudStore cloudStore = new MockCloudStore(); store.setCloudStore(cloudStore); zts.cloudStore = cloudStore; Principal principal = SimplePrincipal.create("user_domain", "user1", "v=U1;d=user_domain;n=user;s=signature", 0, null); ResourceContext context = createResourceContext(principal); InstanceCertManager certManager = Mockito.mock(InstanceCertManager.class); Mockito.when(certManager.generateIdentity(csr, "user_domain.user1", "client", 3600)).thenReturn(null); zts.instanceCertManager = certManager; try { zts.postRoleCertificateRequestExt(context, req); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 500); assertTrue(ex.getMessage().contains("Unable to create certificate from the cert signer")); } }
@Test public void testPostRoleCertificateExtInvalidRoleDomain() throws IOException { Path path = Paths.get("src/test/resources/athenz_coretech_role_uri.csr"); String csr = new String(Files.readAllBytes(path)); RoleCertificateRequest req = new RoleCertificateRequest() .setCsr(csr).setExpiryTime(3600L); CloudStore cloudStore = new MockCloudStore(); store.setCloudStore(cloudStore); zts.cloudStore = cloudStore; Principal principal = SimplePrincipal.create("user_domain", "user1", "v=U1;d=user_domain;n=user1;s=signature", 0, null); ResourceContext context = createResourceContext(principal); try { zts.postRoleCertificateRequestExt(context, req); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 403); assertTrue(ex.getMessage().contains("Not authorized to assume all requested roles by user principal")); } }