001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2020, Connect2id Ltd and contributors. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.oauth2.sdk.dpop; 019 020 021import java.net.URI; 022import java.security.Provider; 023import java.util.Date; 024 025import com.nimbusds.jose.JOSEException; 026import com.nimbusds.jose.JWSAlgorithm; 027import com.nimbusds.jose.JWSHeader; 028import com.nimbusds.jose.JWSSigner; 029import com.nimbusds.jose.crypto.factories.DefaultJWSSignerFactory; 030import com.nimbusds.jose.jwk.JWK; 031import com.nimbusds.jwt.JWTClaimsSet; 032import com.nimbusds.jwt.SignedJWT; 033import com.nimbusds.oauth2.sdk.id.JWTID; 034 035 036/** 037 * Default DPoP JWT factory. 038 */ 039public class DefaultDPoPJWTFactory implements DPoPJWTFactory { 040 041 042 /** 043 * The public signing JWK. 044 */ 045 private final JWK publicJWK; 046 047 048 /** 049 * The signing JWS algorith. 050 */ 051 private final JWSAlgorithm jwsAlg; 052 053 054 /** 055 * The JWS signer. 056 */ 057 private final JWSSigner jwsSigner; 058 059 060 /** 061 * Creates a new DPoP JWT factory using the default JCA provider. 062 * 063 * @param jwk The signing JWK. Must not be {@code null}. 064 * @param jwsAlg The signing JWS algorithm. Must not be {@code null}. 065 * 066 * @throws JOSEException If signer creation failed. 067 */ 068 public DefaultDPoPJWTFactory(final JWK jwk, final JWSAlgorithm jwsAlg) 069 throws JOSEException { 070 071 this(jwk, jwsAlg, null); 072 } 073 074 075 /** 076 * Creates a new DPoP JWT factory. 077 * 078 * @param jwk The signing JWK. Must not be {@code null}. 079 * @param jwsAlg The signing JWS algorithm. Must not be 080 * {@code null}. 081 * @param jcaProvider The JCA provider to use for signing, {@code null} 082 * to use the default. 083 * 084 * @throws JOSEException If signer creation failed. 085 */ 086 public DefaultDPoPJWTFactory(final JWK jwk, final JWSAlgorithm jwsAlg, final Provider jcaProvider) 087 throws JOSEException { 088 089 if (! jwk.isPrivate()) { 090 throw new IllegalArgumentException("The JWK must include private parameters"); 091 } 092 093 if (! JWSAlgorithm.Family.SIGNATURE.contains(jwsAlg)) { 094 throw new IllegalArgumentException("The JWS algorithm must be for a digital signature"); 095 } 096 097 this.jwsAlg = jwsAlg; 098 099 DefaultJWSSignerFactory factory = new DefaultJWSSignerFactory(); 100 if (jcaProvider != null) { 101 factory.getJCAContext().setProvider(jcaProvider); 102 } 103 jwsSigner = factory.createJWSSigner(jwk, jwsAlg); 104 105 publicJWK = jwk.toPublicJWK(); 106 } 107 108 109 /** 110 * Returns the configured public signing JWK. 111 * 112 * @return The public signing JWK. 113 */ 114 public JWK getPublicJWK() { 115 return publicJWK; 116 } 117 118 119 /** 120 * Returns the configured JWS algorithm. 121 * 122 * @return The JWS algorithm. 123 */ 124 public JWSAlgorithm getJWSAlgorithm() { 125 return jwsAlg; 126 } 127 128 129 /** 130 * Returns the JWS signer. 131 * 132 * @return The JWS signer. 133 */ 134 public JWSSigner getJWSSigner() { 135 return jwsSigner; 136 } 137 138 139 @Override 140 public SignedJWT createDPoPJWT(final String htm, 141 final URI htu) 142 throws JOSEException { 143 144 return createDPoPJWT(new JWTID(MINIMAL_JTI_BYTE_LENGTH), htm, htu, new Date()); 145 } 146 147 148 @Override 149 public SignedJWT createDPoPJWT(final JWTID jti, 150 final String htm, 151 final URI htu, 152 final Date iat) 153 throws JOSEException { 154 155 JWSHeader jwsHeader = new JWSHeader.Builder(getJWSAlgorithm()) 156 .type(TYPE) 157 .jwk(getPublicJWK()) 158 .build(); 159 160 JWTClaimsSet jwtClaimsSet = DPoPUtils.createJWTClaimsSet(jti, htm, htu, iat); 161 SignedJWT signedJWT = new SignedJWT(jwsHeader, jwtClaimsSet); 162 signedJWT.sign(getJWSSigner()); 163 return signedJWT; 164 } 165}