Search in sources :

Example 1 with JwtEcdsaAlgorithm

use of com.google.crypto.tink.proto.JwtEcdsaAlgorithm in project tink by google.

the class JwkSetConverter method convertToEcdsaKey.

private static KeyData convertToEcdsaKey(JsonObject jsonKey) throws IOException {
    JwtEcdsaAlgorithm algorithm;
    switch(getStringItem(jsonKey, "alg")) {
        case "ES256":
            expectStringItem(jsonKey, "crv", "P-256");
            algorithm = JwtEcdsaAlgorithm.ES256;
            break;
        case "ES384":
            expectStringItem(jsonKey, "crv", "P-384");
            algorithm = JwtEcdsaAlgorithm.ES384;
            break;
        case "ES512":
            expectStringItem(jsonKey, "crv", "P-521");
            algorithm = JwtEcdsaAlgorithm.ES512;
            break;
        default:
            throw new IOException("Unknown Ecdsa Algorithm: " + getStringItem(jsonKey, "alg"));
    }
    if (jsonKey.has("d")) {
        throw new UnsupportedOperationException("importing ECDSA private keys is not implemented");
    }
    expectStringItem(jsonKey, "kty", "EC");
    validateUseIsSig(jsonKey);
    validateKeyOpsIsVerify(jsonKey);
    JwtEcdsaPublicKey.Builder ecdsaPubKeyBuilder = JwtEcdsaPublicKey.newBuilder().setVersion(0).setAlgorithm(algorithm).setX(ByteString.copyFrom(Base64.urlSafeDecode(getStringItem(jsonKey, "x")))).setY(ByteString.copyFrom(Base64.urlSafeDecode(getStringItem(jsonKey, "y"))));
    if (jsonKey.has("kid")) {
        ecdsaPubKeyBuilder.setCustomKid(JwtEcdsaPublicKey.CustomKid.newBuilder().setValue(getStringItem(jsonKey, "kid")).build());
    }
    return KeyData.newBuilder().setTypeUrl(JWT_ECDSA_PUBLIC_KEY_URL).setValue(ecdsaPubKeyBuilder.build().toByteString()).setKeyMaterialType(KeyMaterialType.ASYMMETRIC_PUBLIC).build();
}
Also used : JwtEcdsaPublicKey(com.google.crypto.tink.proto.JwtEcdsaPublicKey) IOException(java.io.IOException) JwtEcdsaAlgorithm(com.google.crypto.tink.proto.JwtEcdsaAlgorithm)

Example 2 with JwtEcdsaAlgorithm

use of com.google.crypto.tink.proto.JwtEcdsaAlgorithm in project tink by google.

the class JwtEcdsaSignKeyManagerTest method createSignVerifyTink_withDifferentHeaders.

@Test
public void createSignVerifyTink_withDifferentHeaders() throws Exception {
    // KeysetHandle.generateNew is too slow in Tsan.
    assumeFalse(TestUtil.isTsan());
    KeyTemplate template = KeyTemplates.get("JWT_ES256");
    KeysetHandle handle = KeysetHandle.generateNew(template);
    Keyset keyset = CleartextKeysetHandle.getKeyset(handle);
    JwtEcdsaPrivateKey keyProto = JwtEcdsaPrivateKey.parseFrom(keyset.getKey(0).getKeyData().getValue(), ExtensionRegistryLite.getEmptyRegistry());
    ECPrivateKey privateKey = EllipticCurves.getEcPrivateKey(JwtEcdsaVerifyKeyManager.getCurve(keyProto.getPublicKey().getAlgorithm()), keyProto.getKeyValue().toByteArray());
    JwtEcdsaAlgorithm algorithm = keyProto.getPublicKey().getAlgorithm();
    Enums.HashType hash = JwtEcdsaVerifyKeyManager.hashForEcdsaAlgorithm(algorithm);
    EcdsaSignJce rawSigner = new EcdsaSignJce(privateKey, hash, EcdsaEncoding.IEEE_P1363);
    String kid = JwtFormat.getKid(keyset.getKey(0).getKeyId(), keyset.getKey(0).getOutputPrefixType()).get();
    JsonObject payload = new JsonObject();
    payload.addProperty("jti", "jwtId");
    JwtValidator validator = JwtValidator.newBuilder().allowMissingExpiration().build();
    JwtPublicKeyVerify verifier = handle.getPublicKeysetHandle().getPrimitive(JwtPublicKeyVerify.class);
    // Normal, valid signed token.
    JsonObject normalHeader = new JsonObject();
    normalHeader.addProperty("alg", "ES256");
    normalHeader.addProperty("kid", kid);
    String normalToken = generateSignedCompact(rawSigner, normalHeader, payload);
    verifier.verifyAndDecode(normalToken, validator);
    // token without kid are rejected, even if they are valid.
    JsonObject headerWithoutKid = new JsonObject();
    headerWithoutKid.addProperty("alg", "ES256");
    String tokenWithoutKid = generateSignedCompact(rawSigner, headerWithoutKid, payload);
    assertThrows(GeneralSecurityException.class, () -> verifier.verifyAndDecode(tokenWithoutKid, validator));
    // token without algorithm in the header
    JsonObject headerWithoutAlg = new JsonObject();
    headerWithoutAlg.addProperty("kid", kid);
    String tokenWithoutAlg = generateSignedCompact(rawSigner, headerWithoutAlg, payload);
    assertThrows(GeneralSecurityException.class, () -> verifier.verifyAndDecode(tokenWithoutAlg, validator));
    // token with an incorrect algorithm in the header
    JsonObject headerWithBadAlg = new JsonObject();
    headerWithBadAlg.addProperty("kid", kid);
    headerWithBadAlg.addProperty("alg", "RS256");
    String badAlgToken = generateSignedCompact(rawSigner, headerWithBadAlg, payload);
    assertThrows(GeneralSecurityException.class, () -> verifier.verifyAndDecode(badAlgToken, validator));
    // token with an unknown kid header
    JsonObject unknownKidHeader = new JsonObject();
    unknownKidHeader.addProperty("alg", "ES256");
    unknownKidHeader.addProperty("kid", "unknown");
    String unknownKidSignedCompact = generateSignedCompact(rawSigner, unknownKidHeader, payload);
    assertThrows(GeneralSecurityException.class, () -> verifier.verifyAndDecode(unknownKidSignedCompact, validator));
}
Also used : KeysetHandle(com.google.crypto.tink.KeysetHandle) CleartextKeysetHandle(com.google.crypto.tink.CleartextKeysetHandle) Keyset(com.google.crypto.tink.proto.Keyset) ECPrivateKey(java.security.interfaces.ECPrivateKey) JsonObject(com.google.gson.JsonObject) ByteString(com.google.protobuf.ByteString) JwtEcdsaPrivateKey(com.google.crypto.tink.proto.JwtEcdsaPrivateKey) Enums(com.google.crypto.tink.subtle.Enums) EcdsaSignJce(com.google.crypto.tink.subtle.EcdsaSignJce) JwtEcdsaAlgorithm(com.google.crypto.tink.proto.JwtEcdsaAlgorithm) KeyTemplate(com.google.crypto.tink.KeyTemplate) Test(org.junit.Test)

Example 3 with JwtEcdsaAlgorithm

use of com.google.crypto.tink.proto.JwtEcdsaAlgorithm in project tink by google.

the class JwtEcdsaSignKeyManagerTest method createSignVerifyRaw_withDifferentHeaders.

@Test
public void createSignVerifyRaw_withDifferentHeaders() throws Exception {
    // KeysetHandle.generateNew is too slow in Tsan.
    assumeFalse(TestUtil.isTsan());
    KeyTemplate template = KeyTemplates.get("JWT_ES256_RAW");
    KeysetHandle handle = KeysetHandle.generateNew(template);
    Keyset keyset = CleartextKeysetHandle.getKeyset(handle);
    JwtEcdsaPrivateKey keyProto = JwtEcdsaPrivateKey.parseFrom(keyset.getKey(0).getKeyData().getValue(), ExtensionRegistryLite.getEmptyRegistry());
    ECPrivateKey privateKey = EllipticCurves.getEcPrivateKey(JwtEcdsaVerifyKeyManager.getCurve(keyProto.getPublicKey().getAlgorithm()), keyProto.getKeyValue().toByteArray());
    JwtEcdsaAlgorithm algorithm = keyProto.getPublicKey().getAlgorithm();
    Enums.HashType hash = JwtEcdsaVerifyKeyManager.hashForEcdsaAlgorithm(algorithm);
    EcdsaSignJce rawSigner = new EcdsaSignJce(privateKey, hash, EcdsaEncoding.IEEE_P1363);
    JsonObject payload = new JsonObject();
    payload.addProperty("jid", "jwtId");
    JwtValidator validator = JwtValidator.newBuilder().allowMissingExpiration().build();
    JwtPublicKeyVerify verifier = handle.getPublicKeysetHandle().getPrimitive(JwtPublicKeyVerify.class);
    // Normal, valid signed compact.
    JsonObject normalHeader = new JsonObject();
    normalHeader.addProperty("alg", "ES256");
    String normalSignedCompact = generateSignedCompact(rawSigner, normalHeader, payload);
    verifier.verifyAndDecode(normalSignedCompact, validator);
    // valid token, with "typ" set in the header
    JsonObject goodHeader = new JsonObject();
    goodHeader.addProperty("alg", "ES256");
    goodHeader.addProperty("typ", "typeHeader");
    String goodSignedCompact = generateSignedCompact(rawSigner, goodHeader, payload);
    verifier.verifyAndDecode(goodSignedCompact, JwtValidator.newBuilder().expectTypeHeader("typeHeader").allowMissingExpiration().build());
    // invalid token with an empty header
    JsonObject emptyHeader = new JsonObject();
    String emptyHeaderSignedCompact = generateSignedCompact(rawSigner, emptyHeader, payload);
    assertThrows(GeneralSecurityException.class, () -> verifier.verifyAndDecode(emptyHeaderSignedCompact, validator));
    // invalid token with a valid but incorrect algorithm in the header
    JsonObject badAlgoHeader = new JsonObject();
    badAlgoHeader.addProperty("alg", "RS256");
    String badAlgoSignedCompact = generateSignedCompact(rawSigner, badAlgoHeader, payload);
    assertThrows(GeneralSecurityException.class, () -> verifier.verifyAndDecode(badAlgoSignedCompact, validator));
    // for raw keys, the validation should work even if a "kid" header is present.
    JsonObject unknownKidHeader = new JsonObject();
    unknownKidHeader.addProperty("alg", "ES256");
    unknownKidHeader.addProperty("kid", "unknown");
    String unknownKidSignedCompact = generateSignedCompact(rawSigner, unknownKidHeader, payload);
    verifier.verifyAndDecode(unknownKidSignedCompact, validator);
}
Also used : KeysetHandle(com.google.crypto.tink.KeysetHandle) CleartextKeysetHandle(com.google.crypto.tink.CleartextKeysetHandle) Keyset(com.google.crypto.tink.proto.Keyset) ECPrivateKey(java.security.interfaces.ECPrivateKey) JsonObject(com.google.gson.JsonObject) ByteString(com.google.protobuf.ByteString) JwtEcdsaPrivateKey(com.google.crypto.tink.proto.JwtEcdsaPrivateKey) Enums(com.google.crypto.tink.subtle.Enums) EcdsaSignJce(com.google.crypto.tink.subtle.EcdsaSignJce) JwtEcdsaAlgorithm(com.google.crypto.tink.proto.JwtEcdsaAlgorithm) KeyTemplate(com.google.crypto.tink.KeyTemplate) Test(org.junit.Test)

Example 4 with JwtEcdsaAlgorithm

use of com.google.crypto.tink.proto.JwtEcdsaAlgorithm in project tink by google.

the class JwtEcdsaSignKeyManager method keyFactory.

@Override
public KeyFactory<JwtEcdsaKeyFormat, JwtEcdsaPrivateKey> keyFactory() {
    return new KeyFactory<JwtEcdsaKeyFormat, JwtEcdsaPrivateKey>(JwtEcdsaKeyFormat.class) {

        @Override
        public void validateKeyFormat(JwtEcdsaKeyFormat format) throws GeneralSecurityException {
            JwtEcdsaVerifyKeyManager.validateEcdsaAlgorithm(format.getAlgorithm());
        }

        @Override
        public JwtEcdsaKeyFormat parseKeyFormat(ByteString byteString) throws InvalidProtocolBufferException {
            return JwtEcdsaKeyFormat.parseFrom(byteString, ExtensionRegistryLite.getEmptyRegistry());
        }

        @Override
        public JwtEcdsaPrivateKey deriveKey(JwtEcdsaKeyFormat format, InputStream inputStream) {
            throw new UnsupportedOperationException();
        }

        @Override
        public JwtEcdsaPrivateKey createKey(JwtEcdsaKeyFormat format) throws GeneralSecurityException {
            JwtEcdsaAlgorithm ecdsaAlgorithm = format.getAlgorithm();
            KeyPair keyPair = EllipticCurves.generateKeyPair(JwtEcdsaVerifyKeyManager.getCurve(format.getAlgorithm()));
            ECPublicKey pubKey = (ECPublicKey) keyPair.getPublic();
            ECPrivateKey privKey = (ECPrivateKey) keyPair.getPrivate();
            ECPoint w = pubKey.getW();
            // Creates JwtEcdsaPublicKey.
            JwtEcdsaPublicKey ecdsaPubKey = JwtEcdsaPublicKey.newBuilder().setVersion(getVersion()).setAlgorithm(ecdsaAlgorithm).setX(ByteString.copyFrom(w.getAffineX().toByteArray())).setY(ByteString.copyFrom(w.getAffineY().toByteArray())).build();
            // Creates JwtEcdsaPrivateKey.
            return JwtEcdsaPrivateKey.newBuilder().setVersion(getVersion()).setPublicKey(ecdsaPubKey).setKeyValue(ByteString.copyFrom(privKey.getS().toByteArray())).build();
        }

        /**
         * List of default templates to generate tokens with algorithms "ES256", "ES384" or "ES512".
         * Use the template with the "_RAW" suffix if you want to generate tokens without a "kid"
         * header.
         */
        @Override
        public Map<String, KeyFactory.KeyFormat<JwtEcdsaKeyFormat>> keyFormats() {
            Map<String, KeyFactory.KeyFormat<JwtEcdsaKeyFormat>> result = new HashMap<>();
            result.put("JWT_ES256_RAW", createKeyFormat(JwtEcdsaAlgorithm.ES256, KeyTemplate.OutputPrefixType.RAW));
            result.put("JWT_ES256", createKeyFormat(JwtEcdsaAlgorithm.ES256, KeyTemplate.OutputPrefixType.TINK));
            result.put("JWT_ES384_RAW", createKeyFormat(JwtEcdsaAlgorithm.ES384, KeyTemplate.OutputPrefixType.RAW));
            result.put("JWT_ES384", createKeyFormat(JwtEcdsaAlgorithm.ES384, KeyTemplate.OutputPrefixType.TINK));
            result.put("JWT_ES512_RAW", createKeyFormat(JwtEcdsaAlgorithm.ES512, KeyTemplate.OutputPrefixType.RAW));
            result.put("JWT_ES512", createKeyFormat(JwtEcdsaAlgorithm.ES512, KeyTemplate.OutputPrefixType.TINK));
            return Collections.unmodifiableMap(result);
        }
    };
}
Also used : ECPrivateKey(java.security.interfaces.ECPrivateKey) KeyPair(java.security.KeyPair) JwtEcdsaPublicKey(com.google.crypto.tink.proto.JwtEcdsaPublicKey) HashMap(java.util.HashMap) ByteString(com.google.protobuf.ByteString) InputStream(java.io.InputStream) ByteString(com.google.protobuf.ByteString) ECPoint(java.security.spec.ECPoint) JwtEcdsaKeyFormat(com.google.crypto.tink.proto.JwtEcdsaKeyFormat) ECPublicKey(java.security.interfaces.ECPublicKey) JwtEcdsaAlgorithm(com.google.crypto.tink.proto.JwtEcdsaAlgorithm) JwtEcdsaKeyFormat(com.google.crypto.tink.proto.JwtEcdsaKeyFormat)

Aggregations

JwtEcdsaAlgorithm (com.google.crypto.tink.proto.JwtEcdsaAlgorithm)4 ByteString (com.google.protobuf.ByteString)3 ECPrivateKey (java.security.interfaces.ECPrivateKey)3 CleartextKeysetHandle (com.google.crypto.tink.CleartextKeysetHandle)2 KeyTemplate (com.google.crypto.tink.KeyTemplate)2 KeysetHandle (com.google.crypto.tink.KeysetHandle)2 JwtEcdsaPrivateKey (com.google.crypto.tink.proto.JwtEcdsaPrivateKey)2 JwtEcdsaPublicKey (com.google.crypto.tink.proto.JwtEcdsaPublicKey)2 Keyset (com.google.crypto.tink.proto.Keyset)2 EcdsaSignJce (com.google.crypto.tink.subtle.EcdsaSignJce)2 Enums (com.google.crypto.tink.subtle.Enums)2 JsonObject (com.google.gson.JsonObject)2 Test (org.junit.Test)2 JwtEcdsaKeyFormat (com.google.crypto.tink.proto.JwtEcdsaKeyFormat)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 KeyPair (java.security.KeyPair)1 ECPublicKey (java.security.interfaces.ECPublicKey)1 ECPoint (java.security.spec.ECPoint)1 HashMap (java.util.HashMap)1