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}