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}