001/* 002* The contents of this file are subject to the terms of the Common Development and 003* Distribution License (the License). You may not use this file except in compliance with the 004* License. 005* 006* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007* specific language governing permission and limitations under the License. 008* 009* When distributing Covered Software, include this CDDL Header Notice in each file and include 010* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011* Header, with the fields enclosed by brackets [] replaced by your own identifying 012* information: "Portions copyright [year] [name of copyright owner]". 013* 014* Copyright 2014-2016 ForgeRock AS. 015*/ 016 017package org.forgerock.jaspi.modules.openid.resolvers; 018 019import static org.forgerock.caf.authentication.framework.AuthenticationFramework.LOG; 020 021import java.security.PublicKey; 022 023import org.forgerock.jaspi.modules.openid.exceptions.InvalidSignatureException; 024import org.forgerock.jaspi.modules.openid.exceptions.OpenIdConnectVerificationException; 025import org.forgerock.json.jose.jws.SignedJwt; 026import org.forgerock.json.jose.jws.SigningManager; 027 028/** 029 * This class exists to allow functionality for those Open ID Connect providers which 030 * supply their signatures through asymmetric key algorithms (e.g. RSA). In these cases 031 * we want to use a public key (usually retrieved from a Trust Store) to verify the 032 * signature. 033 */ 034public class PublicKeyOpenIdResolverImpl extends BaseOpenIdResolver { 035 036 private final SigningManager signingManager; 037 038 private final PublicKey key; 039 040 /** 041 * Constructor for PublicKeyOpenIdResolverImpl. 042 * 043 * @param issuer The issuer (provider) of the Open Id Connect id token 044 * @param key The public key, used to verify a private-key signed signature 045 */ 046 public PublicKeyOpenIdResolverImpl(String issuer, PublicKey key) { 047 super(issuer); 048 049 signingManager = new SigningManager(); 050 this.key = key; 051 } 052 053 /** 054 * {@inheritDoc} 055 */ 056 @Override 057 public void validateIdentity(final SignedJwt idClaim) throws OpenIdConnectVerificationException { 058 super.validateIdentity(idClaim); 059 verifySignature(idClaim); 060 } 061 062 /** 063 * Verifies that the JWS was signed by the corresponding private key to this 064 * public key. 065 * 066 * @param idClaim The JWS to verify 067 * @throws InvalidSignatureException If the JWS supplied does not match the key for this resolver 068 */ 069 public void verifySignature(final SignedJwt idClaim) throws InvalidSignatureException { 070 if (!idClaim.verify(createSigningHandlerForKey(signingManager, key))) { 071 LOG.debug("JWS signature not signed with supplied key"); 072 throw new InvalidSignatureException("JWS signature not signed with supplied key"); 073 } 074 } 075 076}