001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2021, 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.util.AbstractMap; 022import java.util.Map; 023import java.util.Objects; 024 025import net.jcip.annotations.Immutable; 026import net.minidev.json.JSONObject; 027 028import com.nimbusds.jose.JOSEException; 029import com.nimbusds.jose.jwk.JWK; 030import com.nimbusds.jose.util.Base64URL; 031import com.nimbusds.jwt.JWTClaimsSet; 032import com.nimbusds.oauth2.sdk.ParseException; 033import com.nimbusds.oauth2.sdk.cnf.AbstractConfirmation; 034import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 035 036 037/** 038 * JSON Web Key (JWK) SHA-256 thumbprint confirmation. 039 */ 040@Immutable 041public final class JWKThumbprintConfirmation extends AbstractConfirmation { 042 043 044 /** 045 * The JWK SHA-256 thumbprint. 046 */ 047 private final Base64URL jkt; 048 049 050 /** 051 * Creates a new JWK SHA-256 thumbprint. 052 * 053 * @param jkt The JWK SHA-256 thumbprint. Must not be {@code null}. 054 */ 055 public JWKThumbprintConfirmation(final Base64URL jkt) { 056 057 if (jkt == null) { 058 throw new IllegalArgumentException("The JWK thumbprint must not be null"); 059 } 060 061 this.jkt = jkt; 062 } 063 064 065 /** 066 * Returns the JWK SHA-256 thumbprint. 067 * 068 * @return The JWK SHA-256 thumbprint. 069 */ 070 public Base64URL getValue() { 071 072 return jkt; 073 } 074 075 076 @Override 077 public Map.Entry<String,JSONObject> toJWTClaim() { 078 079 JSONObject cnf = new JSONObject(); 080 cnf.put("jkt", jkt.toString()); 081 082 return new AbstractMap.SimpleImmutableEntry<>( 083 "cnf", 084 cnf 085 ); 086 } 087 088 089 @Override 090 public boolean equals(Object o) { 091 if (this == o) return true; 092 if (!(o instanceof JWKThumbprintConfirmation)) return false; 093 JWKThumbprintConfirmation that = (JWKThumbprintConfirmation) o; 094 return jkt.equals(that.jkt); 095 } 096 097 098 @Override 099 public int hashCode() { 100 return Objects.hash(jkt); 101 } 102 103 104 /** 105 * Parses a JWK SHA-256 thumbprint confirmation from the specified JWT 106 * claims set. 107 * 108 * @param jwtClaimsSet The JWT claims set. 109 * 110 * @return The JWK SHA-256 thumbprint confirmation, {@code null} if not 111 * found. 112 */ 113 public static JWKThumbprintConfirmation parse(final JWTClaimsSet jwtClaimsSet) { 114 115 JSONObject cnf = parseConfirmationJSONObject(jwtClaimsSet); 116 117 if (cnf == null) { 118 return null; 119 } 120 121 return parseFromConfirmationJSONObject(cnf); 122 } 123 124 125 /** 126 * Parses a JWK SHA-256 thumbprint confirmation from the specified JSON 127 * object representation of a JWT claims set. 128 * 129 * @param jsonObject The JSON object. 130 * 131 * @return The JWK SHA-256 thumbprint confirmation, {@code null} if not 132 * found. 133 */ 134 public static JWKThumbprintConfirmation parse(final JSONObject jsonObject) { 135 136 if (! jsonObject.containsKey("cnf")) { 137 return null; 138 } 139 140 try { 141 return parseFromConfirmationJSONObject(JSONObjectUtils.getJSONObject(jsonObject, "cnf")); 142 } catch (ParseException e) { 143 return null; 144 } 145 } 146 147 148 /** 149 * Parses a JWK SHA-256 thumbprint confirmation from the specified 150 * confirmation ("cnf") JSON object. 151 * 152 * @param cnf The confirmation JSON object, {@code null} if none. 153 * 154 * @return The JWK SHA-256 thumbprint confirmation, {@code null} if not 155 * found. 156 */ 157 public static JWKThumbprintConfirmation parseFromConfirmationJSONObject(final JSONObject cnf) { 158 159 if (cnf == null) { 160 return null; 161 } 162 163 try { 164 String jktString = JSONObjectUtils.getString(cnf, "jkt"); 165 return new JWKThumbprintConfirmation(new Base64URL(jktString)); 166 } catch (ParseException e) { 167 return null; 168 } 169 } 170 171 172 /** 173 * Creates a confirmation of the specified JWK. 174 * 175 * @param jwk The JWK. 176 * 177 * @return The JWK SHA-256 thumbprint confirmation. 178 * 179 * @throws JOSEException If the thumbprint computation failed. 180 */ 181 public static JWKThumbprintConfirmation of(final JWK jwk) 182 throws JOSEException { 183 184 return new JWKThumbprintConfirmation(jwk.computeThumbprint()); 185 } 186}