1// Copyright 2022 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 17package jwt 18 19import ( 20 "fmt" 21 22 "google.golang.org/protobuf/proto" 23 "github.com/google/tink/go/internal/tinkerror" 24 jepb "github.com/google/tink/go/proto/jwt_ecdsa_go_proto" 25 jwtmacpb "github.com/google/tink/go/proto/jwt_hmac_go_proto" 26 jrsppb "github.com/google/tink/go/proto/jwt_rsa_ssa_pkcs1_go_proto" 27 jrpsspb "github.com/google/tink/go/proto/jwt_rsa_ssa_pss_go_proto" 28 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 29) 30 31func createJWTHMACKeyTemplate(keySize uint32, algorithm jwtmacpb.JwtHmacAlgorithm, outputPrefixType tinkpb.OutputPrefixType) *tinkpb.KeyTemplate { 32 format := &jwtmacpb.JwtHmacKeyFormat{ 33 KeySize: keySize, 34 Version: jwtHMACKeyVersion, 35 Algorithm: algorithm, 36 } 37 serializedFormat, err := proto.Marshal(format) 38 if err != nil { 39 tinkerror.Fail(fmt.Sprintf("failed to marshal key format: %s", err)) 40 } 41 return &tinkpb.KeyTemplate{ 42 TypeUrl: jwtHMACTypeURL, 43 Value: serializedFormat, 44 OutputPrefixType: outputPrefixType, 45 } 46} 47 48func createJWTECDSAKeyTemplate(algorithm jepb.JwtEcdsaAlgorithm, outputPrefixType tinkpb.OutputPrefixType) *tinkpb.KeyTemplate { 49 format := &jepb.JwtEcdsaKeyFormat{ 50 Version: jwtECDSASignerKeyVersion, 51 Algorithm: algorithm, 52 } 53 serializedFormat, err := proto.Marshal(format) 54 if err != nil { 55 tinkerror.Fail(fmt.Sprintf("failed to marshal key format: %s", err)) 56 } 57 return &tinkpb.KeyTemplate{ 58 TypeUrl: jwtECDSASignerTypeURL, 59 Value: serializedFormat, 60 OutputPrefixType: outputPrefixType, 61 } 62} 63 64func createJWTRSKeyTemplate(algorithm jrsppb.JwtRsaSsaPkcs1Algorithm, modulusSizeInBits uint32, outputPrefixType tinkpb.OutputPrefixType) *tinkpb.KeyTemplate { 65 format := &jrsppb.JwtRsaSsaPkcs1KeyFormat{ 66 Version: jwtRSSignerKeyVersion, 67 Algorithm: algorithm, 68 ModulusSizeInBits: modulusSizeInBits, 69 PublicExponent: []byte{0x01, 0x00, 0x01}, 70 } 71 serializedFormat, err := proto.Marshal(format) 72 if err != nil { 73 tinkerror.Fail(fmt.Sprintf("failed to marshal key format: %s", err)) 74 } 75 return &tinkpb.KeyTemplate{ 76 TypeUrl: jwtRSSignerTypeURL, 77 Value: serializedFormat, 78 OutputPrefixType: outputPrefixType, 79 } 80} 81 82func createJWTPSKeyTemplate(algorithm jrpsspb.JwtRsaSsaPssAlgorithm, modulusSizeInBits uint32, outputPrefixType tinkpb.OutputPrefixType) *tinkpb.KeyTemplate { 83 format := &jrpsspb.JwtRsaSsaPssKeyFormat{ 84 Version: jwtPSSignerKeyVersion, 85 Algorithm: algorithm, 86 PublicExponent: []byte{0x01, 0x00, 0x01}, 87 ModulusSizeInBits: modulusSizeInBits, 88 } 89 serializedFormat, err := proto.Marshal(format) 90 if err != nil { 91 tinkerror.Fail(fmt.Sprintf("failed to marshal key format: %s", err)) 92 } 93 return &tinkpb.KeyTemplate{ 94 TypeUrl: jwtPSSignerTypeURL, 95 Value: serializedFormat, 96 OutputPrefixType: outputPrefixType, 97 } 98} 99 100// HS256Template creates a JWT key template for JWA algorithm "HS256", which is a 101// HMAC-SHA256 with a 32 byte key. It will set a key ID header "kid" in the token. 102func HS256Template() *tinkpb.KeyTemplate { 103 return createJWTHMACKeyTemplate(32, jwtmacpb.JwtHmacAlgorithm_HS256, tinkpb.OutputPrefixType_TINK) 104} 105 106// RawHS256Template creates a JWT key template for JWA algorithm "HS256", which is a 107// HMAC-SHA256 with a 32 byte key. It will not set a key ID header "kid" in the token. 108func RawHS256Template() *tinkpb.KeyTemplate { 109 return createJWTHMACKeyTemplate(32, jwtmacpb.JwtHmacAlgorithm_HS256, tinkpb.OutputPrefixType_RAW) 110} 111 112// HS384Template creates a JWT key template for JWA algorithm "HS384", which is a 113// HMAC-SHA384 with a 48 byte key. It will set a key ID header "kid" in the token. 114func HS384Template() *tinkpb.KeyTemplate { 115 return createJWTHMACKeyTemplate(48, jwtmacpb.JwtHmacAlgorithm_HS384, tinkpb.OutputPrefixType_TINK) 116} 117 118// RawHS384Template creates a JWT key template for JWA algorithm "HS384", which is a 119// HMAC-SHA384 with a 48 byte key. It will not set a key ID header "kid" in the token. 120func RawHS384Template() *tinkpb.KeyTemplate { 121 return createJWTHMACKeyTemplate(48, jwtmacpb.JwtHmacAlgorithm_HS384, tinkpb.OutputPrefixType_RAW) 122} 123 124// HS512Template creates a JWT key template for JWA algorithm "HS512", which is a 125// HMAC-SHA512 with a 64 byte key. It will set a key ID header "kid" in the token. 126func HS512Template() *tinkpb.KeyTemplate { 127 return createJWTHMACKeyTemplate(64, jwtmacpb.JwtHmacAlgorithm_HS512, tinkpb.OutputPrefixType_TINK) 128} 129 130// RawHS512Template creates a JWT key template for JWA algorithm "HS512", which is a 131// HMAC-SHA512 with a 64 byte key. It will not set a key ID header "kid" in the token. 132func RawHS512Template() *tinkpb.KeyTemplate { 133 return createJWTHMACKeyTemplate(64, jwtmacpb.JwtHmacAlgorithm_HS512, tinkpb.OutputPrefixType_RAW) 134} 135 136// ES256Template creates a JWT key template for JWA algorithm "ES256", which is digital 137// signature with the NIST P-256 curve. It will set a key ID header "kid" in the token. 138func ES256Template() *tinkpb.KeyTemplate { 139 return createJWTECDSAKeyTemplate(jepb.JwtEcdsaAlgorithm_ES256, tinkpb.OutputPrefixType_TINK) 140} 141 142// RawES256Template creates a JWT key template for JWA algorithm "ES256", which is digital 143// signature with the NIST P-256 curve. It will not set a key ID header "kid" in the token. 144func RawES256Template() *tinkpb.KeyTemplate { 145 return createJWTECDSAKeyTemplate(jepb.JwtEcdsaAlgorithm_ES256, tinkpb.OutputPrefixType_RAW) 146} 147 148// ES384Template creates a JWT key template for JWA algorithm "ES384", which is digital 149// signature with the NIST P-384 curve. It will set a key ID header "kid" in the token. 150func ES384Template() *tinkpb.KeyTemplate { 151 return createJWTECDSAKeyTemplate(jepb.JwtEcdsaAlgorithm_ES384, tinkpb.OutputPrefixType_TINK) 152} 153 154// RawES384Template creates a JWT key template for JWA algorithm "ES384", which is digital 155// signature with the NIST P-384 curve. It will not set a key ID header "kid" in the token. 156func RawES384Template() *tinkpb.KeyTemplate { 157 return createJWTECDSAKeyTemplate(jepb.JwtEcdsaAlgorithm_ES384, tinkpb.OutputPrefixType_RAW) 158} 159 160// ES512Template creates a JWT key template for JWA algorithm "ES512", which is digital 161// signature with the NIST P-521 curve. It will set a key ID header "kid" in the token. 162func ES512Template() *tinkpb.KeyTemplate { 163 return createJWTECDSAKeyTemplate(jepb.JwtEcdsaAlgorithm_ES512, tinkpb.OutputPrefixType_TINK) 164} 165 166// RawES512Template creates a JWT key template for JWA algorithm "ES512", which is digital 167// signature with the NIST P-521 curve. It will not set a key ID header "kid" in the token. 168func RawES512Template() *tinkpb.KeyTemplate { 169 return createJWTECDSAKeyTemplate(jepb.JwtEcdsaAlgorithm_ES512, tinkpb.OutputPrefixType_RAW) 170} 171 172// RS256_2048_F4_Key_Template creates a JWT key template for JWA algorithm "RS256", which is digital 173// signature with RSA-SSA-PKCS1 and SHA256. It will set a key ID header "kid" in the token. 174func RS256_2048_F4_Key_Template() *tinkpb.KeyTemplate { 175 return createJWTRSKeyTemplate(jrsppb.JwtRsaSsaPkcs1Algorithm_RS256, 2048, tinkpb.OutputPrefixType_TINK) 176} 177 178// RawRS256_2048_F4_Key_Template creates a JWT key template for JWA algorithm "RS256", which is digital 179// signature with RSA-SSA-PKCS1 and SHA256. It will not set a key ID header "kid" in the token. 180func RawRS256_2048_F4_Key_Template() *tinkpb.KeyTemplate { 181 return createJWTRSKeyTemplate(jrsppb.JwtRsaSsaPkcs1Algorithm_RS256, 2048, tinkpb.OutputPrefixType_RAW) 182} 183 184// RS256_3072_F4_Key_Template creates a JWT key template for JWA algorithm "RS256", which is digital 185// signature with RSA-SSA-PKCS1 and SHA256. It will set a key ID header "kid" in the token. 186func RS256_3072_F4_Key_Template() *tinkpb.KeyTemplate { 187 return createJWTRSKeyTemplate(jrsppb.JwtRsaSsaPkcs1Algorithm_RS256, 3072, tinkpb.OutputPrefixType_TINK) 188} 189 190// RawRS256_3072_F4_Key_Template creates a JWT key template for JWA algorithm "RS256", which is digital 191// signature with RSA-SSA-PKCS1 and SHA256. It will not set a key ID header "kid" in the token. 192func RawRS256_3072_F4_Key_Template() *tinkpb.KeyTemplate { 193 return createJWTRSKeyTemplate(jrsppb.JwtRsaSsaPkcs1Algorithm_RS256, 3072, tinkpb.OutputPrefixType_RAW) 194} 195 196// RS384_3072_F4_Key_Template creates a JWT key template for JWA algorithm "RS384", which is digital 197// signature with RSA-SSA-PKCS1 and SHA384. It will set a key ID header "kid" in the token. 198func RS384_3072_F4_Key_Template() *tinkpb.KeyTemplate { 199 return createJWTRSKeyTemplate(jrsppb.JwtRsaSsaPkcs1Algorithm_RS384, 3072, tinkpb.OutputPrefixType_TINK) 200} 201 202// RawRS384_3072_F4_Key_Template creates a JWT key template for JWA algorithm "RS384", which is digital 203// signature with RSA-SSA-PKCS1 and SHA384. It will not set a key ID header "kid" in the token. 204func RawRS384_3072_F4_Key_Template() *tinkpb.KeyTemplate { 205 return createJWTRSKeyTemplate(jrsppb.JwtRsaSsaPkcs1Algorithm_RS384, 3072, tinkpb.OutputPrefixType_RAW) 206} 207 208// RS512_4096_F4_Key_Template creates a JWT key template for JWA algorithm "RS512", which is digital 209// signature with RSA-SSA-PKCS1 and SHA512. It will set a key ID header "kid" in the token. 210func RS512_4096_F4_Key_Template() *tinkpb.KeyTemplate { 211 return createJWTRSKeyTemplate(jrsppb.JwtRsaSsaPkcs1Algorithm_RS512, 4096, tinkpb.OutputPrefixType_TINK) 212} 213 214// RawRS512_4096_F4_Key_Template creates a JWT key template for JWA algorithm "RS512", which is digital 215// signature with RSA-SSA-PKCS1 and SHA512. It will not set a key ID header "kid" in the token. 216func RawRS512_4096_F4_Key_Template() *tinkpb.KeyTemplate { 217 return createJWTRSKeyTemplate(jrsppb.JwtRsaSsaPkcs1Algorithm_RS512, 4096, tinkpb.OutputPrefixType_RAW) 218} 219 220// PS256_2048_F4_Key_Template creates a JWT key template for JWA algorithm "PS256", which is digital 221// signature with RSA-SSA-PSS, a 2048 bit modulus, and SHA256. It will set a key ID header "kid" in the token. 222func PS256_2048_F4_Key_Template() *tinkpb.KeyTemplate { 223 return createJWTPSKeyTemplate(jrpsspb.JwtRsaSsaPssAlgorithm_PS256, 2048, tinkpb.OutputPrefixType_TINK) 224} 225 226// RawPS256_2048_F4_Key_Template creates a JWT key template for JWA algorithm "PS256", which is digital 227// signature with RSA-SSA-PSS, a 2048 bit modulus, and SHA256. It will not set a key ID header "kid" in the token. 228func RawPS256_2048_F4_Key_Template() *tinkpb.KeyTemplate { 229 return createJWTPSKeyTemplate(jrpsspb.JwtRsaSsaPssAlgorithm_PS256, 2048, tinkpb.OutputPrefixType_RAW) 230} 231 232// PS256_3072_F4_Key_Template creates a JWT key template for JWA algorithm "PS256", which is digital 233// signature with RSA-SSA-PSS, a 3072 bit modulus, and SHA256. It will set a key ID header "kid" in the token. 234func PS256_3072_F4_Key_Template() *tinkpb.KeyTemplate { 235 return createJWTPSKeyTemplate(jrpsspb.JwtRsaSsaPssAlgorithm_PS256, 3072, tinkpb.OutputPrefixType_TINK) 236} 237 238// RawPS256_3072_F4_Key_Template creates a JWT key template for JWA algorithm "PS256", which is digital 239// signature with RSA-SSA-PSS, a 3072 bit modulus, and SHA256. It will not set a key ID header "kid" in the token. 240func RawPS256_3072_F4_Key_Template() *tinkpb.KeyTemplate { 241 return createJWTPSKeyTemplate(jrpsspb.JwtRsaSsaPssAlgorithm_PS256, 3072, tinkpb.OutputPrefixType_RAW) 242} 243 244// PS384_3072_F4_Key_Template creates a JWT key template for JWA algorithm "PS384", which is digital 245// signature with RSA-SSA-PSS, a 3072 bit modulus, and SHA384. It will set a key ID header "kid" in the token. 246func PS384_3072_F4_Key_Template() *tinkpb.KeyTemplate { 247 return createJWTPSKeyTemplate(jrpsspb.JwtRsaSsaPssAlgorithm_PS384, 3072, tinkpb.OutputPrefixType_TINK) 248} 249 250// RawPS384_3072_F4_Key_Template creates a JWT key template for JWA algorithm "PS384", which is digital 251// signature with RSA-SSA-PSS, a 3072 bit modulus, and SHA384. It will not set a key ID header "kid" in the token. 252func RawPS384_3072_F4_Key_Template() *tinkpb.KeyTemplate { 253 return createJWTPSKeyTemplate(jrpsspb.JwtRsaSsaPssAlgorithm_PS384, 3072, tinkpb.OutputPrefixType_RAW) 254} 255 256// PS512_4096_F4_Key_Template creates a JWT key template for JWA algorithm "PS512", which is digital 257// signature with RSA-SSA-PSS, a 4096 bit modulus, and SHA512. It will set a key ID header "kid" in the token. 258func PS512_4096_F4_Key_Template() *tinkpb.KeyTemplate { 259 return createJWTPSKeyTemplate(jrpsspb.JwtRsaSsaPssAlgorithm_PS512, 4096, tinkpb.OutputPrefixType_TINK) 260} 261 262// RawPS512_4096_F4_Key_Template creates a JWT key template for JWA algorithm "PS512", which is digital 263// signature with RSA-SSA-PSS, a 4096 bit modulus, and SHA512. It will not set a key ID header "kid" in the token. 264func RawPS512_4096_F4_Key_Template() *tinkpb.KeyTemplate { 265 return createJWTPSKeyTemplate(jrpsspb.JwtRsaSsaPssAlgorithm_PS512, 4096, tinkpb.OutputPrefixType_RAW) 266} 267