001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, 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.jose.jwk;
019
020
021import java.net.URI;
022import java.net.URISyntaxException;
023import java.text.ParseException;
024import java.util.Objects;
025
026import net.jcip.annotations.Immutable;
027
028import com.nimbusds.jose.JOSEException;
029import com.nimbusds.jose.util.Base64URL;
030
031
032/**
033 * JSON Web Key (JWK) thumbprint URI.
034 *
035 * <p>See draft-ietf-oauth-jwk-thumbprint-uri
036 *
037 * @author Vladimir Dzhuvinov
038 * @version 2022-01-30
039 */
040@Immutable
041public class ThumbprintURI {
042        
043        
044        /**
045         * The URI prefix of JWK thumbprints.
046         */
047        public static final String PREFIX = "urn:ietf:params:oauth:jwk-thumbprint:";
048        
049        
050        /**
051         * The thumbprint value;
052         */
053        private final Base64URL thumbprint;
054        
055        
056        /**
057         * Creates a new JWK thumbprint URI.
058         *
059         * @param thumbprint the thumbprint value. Must not be {@code null}.
060         */
061        public ThumbprintURI(final Base64URL thumbprint) {
062                if (thumbprint == null) {
063                        throw new IllegalArgumentException("The thumbprint must not be null");
064                }
065                this.thumbprint = thumbprint;
066        }
067        
068        
069        /**
070         * Returns the underlying thumbprint value.
071         *
072         * @return The thumbprint value.
073         */
074        public Base64URL getThumbprint() {
075                
076                return thumbprint;
077        }
078        
079        
080        /**
081         * Returns the {@link URI} representation.
082         *
083         * @return The {@link URI} representation.
084         */
085        public URI toURI() {
086                
087                return URI.create(PREFIX + thumbprint);
088        }
089        
090        
091        @Override
092        public String toString() {
093                
094                return PREFIX + thumbprint;
095        }
096        
097        
098        @Override
099        public boolean equals(Object o) {
100                if (this == o) return true;
101                if (!(o instanceof ThumbprintURI)) return false;
102                ThumbprintURI that = (ThumbprintURI) o;
103                return getThumbprint().equals(that.getThumbprint());
104        }
105        
106        
107        @Override
108        public int hashCode() {
109                return Objects.hash(getThumbprint());
110        }
111        
112        
113        /**
114         * Computes the SHA-256 JWK thumbprint URI for the specified JWK.
115         *
116         * @param jwk The JWK. Must not be {@code null}.
117         *
118         * @return The SHA-256 JWK thumbprint URI.
119         *
120         * @throws JOSEException If the SHA-256 hash algorithm is not
121         *                       supported.
122         */
123        public static ThumbprintURI compute(final JWK jwk)
124                throws JOSEException {
125                
126                return new ThumbprintURI(jwk.computeThumbprint());
127        }
128        
129        
130        /**
131         * Parses a JWK thumbprint URI from the specified URI.
132         *
133         * @param uri The URI. Must not be {@code null}.
134         *
135         * @return The JWK thumbprint URI.
136         *
137         * @throws ParseException If the URI is illegal.
138         */
139        public static ThumbprintURI parse(final URI uri)
140                throws ParseException {
141                
142                String uriString = uri.toString();
143                
144                if (! uriString.startsWith(PREFIX)) {
145                        throw new ParseException("Illegal JWK thumbprint prefix", 0);
146                }
147                
148                String thumbprintValue = uriString.substring(PREFIX.length());
149                
150                if (thumbprintValue.isEmpty()) {
151                        throw new ParseException("Illegal JWK thumbprint: Empty value", 0);
152                }
153                
154                return new ThumbprintURI(new Base64URL(thumbprintValue));
155        }
156        
157        
158        /**
159         * Parses a JWK thumbprint URI from the specified URI string.
160         *
161         * @param s The URI string. Must not be {@code null}.
162         *
163         * @return The JWK thumbprint URI.
164         *
165         * @throws ParseException If the URI string is illegal.
166         */
167        public static ThumbprintURI parse(final String s)
168                throws ParseException {
169                
170                try {
171                        return parse(new URI(s));
172                } catch (URISyntaxException e) {
173                        throw new ParseException(e.getMessage(), 0);
174                }
175        }
176}