xref: /aosp_15_r20/external/tink/java_src/src/main/java/com/google/crypto/tink/jwt/JwtPublicKeyVerifyWrapper.java (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2021 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16 
17 package com.google.crypto.tink.jwt;
18 
19 import com.google.crypto.tink.PrimitiveSet;
20 import com.google.crypto.tink.PrimitiveWrapper;
21 import com.google.crypto.tink.Registry;
22 import com.google.crypto.tink.proto.OutputPrefixType;
23 import com.google.errorprone.annotations.Immutable;
24 import java.security.GeneralSecurityException;
25 import java.util.List;
26 import java.util.Optional;
27 
28 /** The implementation of {@code PrimitiveWrapper<JwtPublicKeyVerify>}. */
29 class JwtPublicKeyVerifyWrapper
30     implements PrimitiveWrapper<JwtPublicKeyVerifyInternal, JwtPublicKeyVerify> {
31 
32   private static final JwtPublicKeyVerifyWrapper WRAPPER = new JwtPublicKeyVerifyWrapper();
33 
validate(PrimitiveSet<JwtPublicKeyVerifyInternal> primitiveSet)34   private static void validate(PrimitiveSet<JwtPublicKeyVerifyInternal> primitiveSet)
35       throws GeneralSecurityException {
36     for (List<PrimitiveSet.Entry<JwtPublicKeyVerifyInternal>> entries : primitiveSet.getAll()) {
37       for (PrimitiveSet.Entry<JwtPublicKeyVerifyInternal> entry : entries) {
38         if ((entry.getOutputPrefixType() != OutputPrefixType.RAW)
39             && (entry.getOutputPrefixType() != OutputPrefixType.TINK)) {
40           throw new GeneralSecurityException("unsupported OutputPrefixType");
41         }
42       }
43     }
44   }
45 
46   @Immutable
47   private static class WrappedJwtPublicKeyVerify implements JwtPublicKeyVerify {
48 
49     @SuppressWarnings("Immutable")
50     private final PrimitiveSet<JwtPublicKeyVerifyInternal> primitives;
51 
WrappedJwtPublicKeyVerify(PrimitiveSet<JwtPublicKeyVerifyInternal> primitives)52     public WrappedJwtPublicKeyVerify(PrimitiveSet<JwtPublicKeyVerifyInternal> primitives) {
53       this.primitives = primitives;
54     }
55 
56     @Override
verifyAndDecode(String compact, JwtValidator validator)57     public VerifiedJwt verifyAndDecode(String compact, JwtValidator validator)
58         throws GeneralSecurityException {
59       GeneralSecurityException interestingException = null;
60       for (List<PrimitiveSet.Entry<JwtPublicKeyVerifyInternal>> entries : primitives.getAll()) {
61         for (PrimitiveSet.Entry<JwtPublicKeyVerifyInternal> entry : entries) {
62           try {
63             Optional<String> kid = JwtFormat.getKid(entry.getKeyId(), entry.getOutputPrefixType());
64             return entry.getPrimitive().verifyAndDecodeWithKid(compact, validator, kid);
65           } catch (GeneralSecurityException e) {
66             if (e instanceof JwtInvalidException) {
67               // Keep this exception so that we are able to throw a meaningful message in the end
68               interestingException = e;
69             }
70             // Ignored as we want to continue verification with other raw keys.
71           }
72         }
73       }
74       if (interestingException != null) {
75         throw interestingException;
76       }
77       throw new GeneralSecurityException("invalid JWT");
78     }
79   }
80 
81   @Override
wrap(final PrimitiveSet<JwtPublicKeyVerifyInternal> primitives)82   public JwtPublicKeyVerify wrap(final PrimitiveSet<JwtPublicKeyVerifyInternal> primitives)
83       throws GeneralSecurityException {
84     validate(primitives);
85     return new WrappedJwtPublicKeyVerify(primitives);
86   }
87 
88   @Override
getPrimitiveClass()89   public Class<JwtPublicKeyVerify> getPrimitiveClass() {
90     return JwtPublicKeyVerify.class;
91   }
92 
93   @Override
getInputPrimitiveClass()94   public Class<JwtPublicKeyVerifyInternal> getInputPrimitiveClass() {
95     return JwtPublicKeyVerifyInternal.class;
96   }
97 
98   /**
99    * Register the wrapper within the registry.
100    *
101    * <p>This is required for calls to {@link Keyset.getPrimitive} with a {@link JwtPublicKeyVerify}
102    * argument.
103    */
register()104   public static void register() throws GeneralSecurityException {
105     Registry.registerPrimitiveWrapper(WRAPPER);
106   }
107 }
108