summaryrefslogtreecommitdiffstats
path: root/vespa-athenz
diff options
context:
space:
mode:
authorHarald Musum <musum@oath.com>2018-07-09 18:03:06 +0200
committerGitHub <noreply@github.com>2018-07-09 18:03:06 +0200
commit3a6cb611e4f1ec8a86f3699c8ddb742e7eac0bdb (patch)
tree30cf4aa444da5966d53a143d9f06a065673df96c /vespa-athenz
parent8cd3b8e9cfe6eb8bf16b2619ef63e1d0f59a1eb0 (diff)
Revert "Move NTokenValidator to vespa-athenz + load pub keys from file"
Diffstat (limited to 'vespa-athenz')
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/api/AthenzPublicKey.java49
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/AthenzConfTruststore.java52
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/AthenzTruststore.java14
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/NTokenValidator.java71
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/package-info.java8
-rw-r--r--vespa-athenz/src/test/java/com/yahoo/vespa/athenz/utils/ntoken/NTokenValidatorTest.java87
6 files changed, 49 insertions, 232 deletions
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/api/AthenzPublicKey.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/api/AthenzPublicKey.java
new file mode 100644
index 00000000000..1c810e3e9c9
--- /dev/null
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/api/AthenzPublicKey.java
@@ -0,0 +1,49 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.athenz.api;
+
+import java.security.PublicKey;
+import java.util.Objects;
+
+/**
+ * @author bjorncs
+ */
+public class AthenzPublicKey {
+
+ private final PublicKey publicKey;
+ private final String keyId;
+
+ public AthenzPublicKey(PublicKey publicKey, String keyId) {
+ this.publicKey = publicKey;
+ this.keyId = keyId;
+ }
+
+ public PublicKey getPublicKey() {
+ return publicKey;
+ }
+
+ public String getKeyId() {
+ return keyId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ AthenzPublicKey that = (AthenzPublicKey) o;
+ return Objects.equals(publicKey, that.publicKey) &&
+ Objects.equals(keyId, that.keyId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(publicKey, keyId);
+ }
+
+ @Override
+ public String toString() {
+ return "AthenzPublicKey{" +
+ "publicKey=" + publicKey +
+ ", keyId='" + keyId + '\'' +
+ '}';
+ }
+}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/AthenzConfTruststore.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/AthenzConfTruststore.java
deleted file mode 100644
index 9d9a19d55cb..00000000000
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/AthenzConfTruststore.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.athenz.utils.ntoken;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.yahoo.athenz.auth.util.Crypto;
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.nio.file.Path;
-import java.security.PublicKey;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-
-/**
- * A {@link AthenzTruststore} that is backed by athenz.conf
- *
- * @author bjorncs
- */
-public class AthenzConfTruststore implements AthenzTruststore {
-
- private final Map<String, PublicKey> publicKeys;
-
- public AthenzConfTruststore(Path athenzConfFile) {
- this.publicKeys = loadPublicKeys(athenzConfFile);
- }
-
- @Override
- public Optional<PublicKey> getPublicKey(String keyId) {
- return Optional.of(publicKeys.get(keyId));
- }
-
- private static Map<String, PublicKey> loadPublicKeys(Path athenzConfFile) {
- try {
- Map<String, PublicKey> publicKeys = new HashMap<>();
- ObjectMapper mapper = new ObjectMapper();
- JsonNode root = mapper.readTree(athenzConfFile.toFile());
- ArrayNode keysArray = (ArrayNode) root.get("ztsPublicKeys");
- for (JsonNode keyEntry : keysArray) {
- String keyId = keyEntry.get("id").textValue();
- String encodedPublicKey = keyEntry.get("key").textValue();
- PublicKey publicKey = Crypto.loadPublicKey(Crypto.ybase64DecodeString(encodedPublicKey));
- publicKeys.put(keyId, publicKey);
- }
- return publicKeys;
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
-}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/AthenzTruststore.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/AthenzTruststore.java
deleted file mode 100644
index 3139e6b847f..00000000000
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/AthenzTruststore.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.athenz.utils.ntoken;
-
-import java.security.PublicKey;
-import java.util.Optional;
-
-/**
- * A truststore that contains all ZMS and ZTS public keys
- *
- * @author bjorncs
- */
-public interface AthenzTruststore {
- Optional<PublicKey> getPublicKey(String keyId);
-}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/NTokenValidator.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/NTokenValidator.java
deleted file mode 100644
index 85c62bc07ff..00000000000
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/NTokenValidator.java
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.athenz.utils.ntoken;
-
-import com.yahoo.athenz.auth.token.PrincipalToken;
-import com.yahoo.log.LogLevel;
-import com.yahoo.vespa.athenz.api.AthenzDomain;
-import com.yahoo.vespa.athenz.api.AthenzPrincipal;
-import com.yahoo.vespa.athenz.api.NToken;
-import com.yahoo.vespa.athenz.utils.AthenzIdentities;
-
-import java.nio.file.Path;
-import java.security.PublicKey;
-import java.time.Duration;
-import java.util.logging.Logger;
-
-/**
- * Validates the content of an NToken:
- * 1) Verifies that the token is signed by Athenz
- * 2) Verifies that the token is not expired
- *
- * @author bjorncs
- */
-public class NTokenValidator {
- // Max allowed skew in token timestamp (only for creation, not expiry timestamp)
- private static final long ALLOWED_TIMESTAMP_OFFSET = Duration.ofMinutes(5).getSeconds();
-
- private static final Logger log = Logger.getLogger(NTokenValidator.class.getName());
- private final AthenzTruststore truststore;
-
-
- public NTokenValidator(AthenzTruststore truststore) {
- this.truststore = truststore;
- }
-
- public NTokenValidator(Path athenzConfFile) {
- this(new AthenzConfTruststore(athenzConfFile));
- }
-
- public AthenzPrincipal validate(NToken token) throws InvalidTokenException {
- PrincipalToken principalToken = new PrincipalToken(token.getRawToken());
- String keyId = principalToken.getKeyId();
- PublicKey zmsPublicKey = truststore.getPublicKey(keyId)
- .orElseThrow(() -> {
- String message = "NToken has an unknown keyId: " + keyId;
- log.log(LogLevel.WARNING, message);
- return new InvalidTokenException(message);
- });
- validateSignatureAndExpiration(principalToken, zmsPublicKey);
- return new AthenzPrincipal(
- AthenzIdentities.from(
- new AthenzDomain(principalToken.getDomain()),
- principalToken.getName()),
- token);
- }
-
- private static void validateSignatureAndExpiration(PrincipalToken token, PublicKey zmsPublicKey) throws InvalidTokenException {
- StringBuilder errorMessageBuilder = new StringBuilder();
- if (!token.validate(zmsPublicKey, (int) ALLOWED_TIMESTAMP_OFFSET, true, errorMessageBuilder)) {
- String message = "NToken is expired or has invalid signature: " + errorMessageBuilder.toString();
- log.log(LogLevel.WARNING, message);
- throw new InvalidTokenException(message);
- }
- }
-
- public static class InvalidTokenException extends RuntimeException {
- public InvalidTokenException(String message) {
- super(message);
- }
- }
-
-}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/package-info.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/package-info.java
deleted file mode 100644
index 8760c02d27d..00000000000
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/utils/ntoken/package-info.java
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-/**
- * @author bjorncs
- */
-@ExportPackage
-package com.yahoo.vespa.athenz.utils.ntoken;
-
-import com.yahoo.osgi.annotation.ExportPackage; \ No newline at end of file
diff --git a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/utils/ntoken/NTokenValidatorTest.java b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/utils/ntoken/NTokenValidatorTest.java
deleted file mode 100644
index 0e70993792f..00000000000
--- a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/utils/ntoken/NTokenValidatorTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.athenz.utils.ntoken;
-
-import com.yahoo.athenz.auth.token.PrincipalToken;
-import com.yahoo.vespa.athenz.api.AthenzIdentity;
-import com.yahoo.vespa.athenz.api.AthenzPrincipal;
-import com.yahoo.vespa.athenz.api.AthenzUser;
-import com.yahoo.vespa.athenz.api.NToken;
-import com.yahoo.vespa.athenz.tls.KeyAlgorithm;
-import com.yahoo.vespa.athenz.tls.KeyUtils;
-import com.yahoo.vespa.athenz.utils.ntoken.NTokenValidator.InvalidTokenException;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import java.security.KeyPair;
-import java.security.PrivateKey;
-import java.time.Instant;
-import java.util.Optional;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * @author bjorncs
- */
-public class NTokenValidatorTest {
-
- private static final KeyPair TRUSTED_KEY = KeyUtils.generateKeypair(KeyAlgorithm.RSA);
- private static final KeyPair UNKNOWN_KEY = KeyUtils.generateKeypair(KeyAlgorithm.RSA);
- private static final AthenzIdentity IDENTITY = AthenzUser.fromUserId("myuser");
-
- @Rule
- public ExpectedException exceptionRule = ExpectedException.none();
-
- @Test
- public void valid_token_is_accepted() throws InvalidTokenException {
- NTokenValidator validator = new NTokenValidator(createTruststore());
- NToken token = createNToken(IDENTITY, Instant.now(), TRUSTED_KEY.getPrivate(), "0");
- AthenzPrincipal principal = validator.validate(token);
- assertEquals("user.myuser", principal.getIdentity().getFullName());
- }
-
- @Test
- public void invalid_signature_is_not_accepted() throws InvalidTokenException {
- NTokenValidator validator = new NTokenValidator(createTruststore());
- NToken token = createNToken(IDENTITY, Instant.now(), UNKNOWN_KEY.getPrivate(), "0");
- exceptionRule.expect(InvalidTokenException.class);
- exceptionRule.expectMessage("NToken is expired or has invalid signature");
- validator.validate(token);
- }
-
- @Test
- public void expired_token_is_not_accepted() throws InvalidTokenException {
- NTokenValidator validator = new NTokenValidator(createTruststore());
- NToken token = createNToken(IDENTITY, Instant.ofEpochMilli(1234) /*long time ago*/, TRUSTED_KEY.getPrivate(), "0");
- exceptionRule.expect(InvalidTokenException.class);
- exceptionRule.expectMessage("NToken is expired or has invalid signature");
- validator.validate(token);
- }
-
- @Test
- public void unknown_keyId_is_not_accepted() throws InvalidTokenException {
- NTokenValidator validator = new NTokenValidator(createTruststore());
- NToken token = createNToken(IDENTITY, Instant.now(), TRUSTED_KEY.getPrivate(), "unknown-key-id");
- exceptionRule.expect(InvalidTokenException.class);
- exceptionRule.expectMessage("NToken has an unknown keyId");
- validator.validate(token);
- }
-
- private static AthenzTruststore createTruststore() {
- return keyId -> keyId.equals("0") ? Optional.of(TRUSTED_KEY.getPublic()) : Optional.empty();
- }
-
- private static NToken createNToken(AthenzIdentity identity, Instant issueTime, PrivateKey privateKey, String keyId) {
- PrincipalToken token = new PrincipalToken.Builder("U1", identity.getDomain().getName(), identity.getName())
- .keyId(keyId)
- .salt("1234")
- .host("host")
- .ip("1.2.3.4")
- .issueTime(issueTime.getEpochSecond())
- .expirationWindow(1000)
- .build();
- token.sign(privateKey);
- return new NToken(token.getSignedToken());
- }
-
-}