001/* 002 * oauth2-oidc-sdk 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.openid.connect.sdk.claims; 019 020 021import java.nio.charset.StandardCharsets; 022import java.security.MessageDigest; 023import java.security.NoSuchAlgorithmException; 024import java.util.Arrays; 025 026import com.nimbusds.jose.JWSAlgorithm; 027import com.nimbusds.jose.jwk.Curve; 028import com.nimbusds.jose.util.Base64URL; 029import com.nimbusds.oauth2.sdk.id.Identifier; 030 031 032/** 033 * The base class for SHA-2 based claims. 034 */ 035public abstract class HashClaim extends Identifier { 036 037 038 private static final long serialVersionUID = -3163141692378087888L; 039 040 041 /** 042 * Creates a new SHA-2 based claim with the specified value. 043 * 044 * @param value The claim value. Must not be {@code null}. 045 */ 046 protected HashClaim(final String value) { 047 048 super(value); 049 } 050 051 052 /** 053 * Gets the matching SHA-2 message digest for the specified JSON Web 054 * Signature (JWS) algorithm. 055 * 056 * @param alg The JWS algorithm. Must not be {@code null}. 057 * 058 * @return The SHA-2 message digest, {@code null} if the JWS algorithm 059 * or its corresponding SHA-2 message digest are not supported. 060 * 061 * @deprecated Use {@link #getMessageDigestInstance(JWSAlgorithm, Curve)} 062 * instead. 063 */ 064 @Deprecated 065 public static MessageDigest getMessageDigestInstance(final JWSAlgorithm alg) { 066 067 return getMessageDigestInstance(alg, null); 068 } 069 070 071 /** 072 * Gets the matching SHA-2 message digest for the specified JSON Web 073 * Signature (JWS) algorithm. 074 * 075 * @param alg The JWS algorithm. Must not be {@code null}. 076 * @param crv The JWK curve used with the JWS algorithm, {@code null} 077 * if not applicable. 078 * 079 * @return The SHA-2 message digest, {@code null} if the JWS algorithm 080 * or its corresponding SHA-2 message digest are not supported. 081 */ 082 public static MessageDigest getMessageDigestInstance(final JWSAlgorithm alg, 083 final Curve crv) { 084 085 String mdAlg; 086 087 if (alg.equals(JWSAlgorithm.HS256) || 088 alg.equals(JWSAlgorithm.RS256) || 089 alg.equals(JWSAlgorithm.ES256) || 090 alg.equals(JWSAlgorithm.ES256K) || 091 alg.equals(JWSAlgorithm.PS256) ) { 092 093 mdAlg = "SHA-256"; 094 095 } else if (alg.equals(JWSAlgorithm.HS384) || 096 alg.equals(JWSAlgorithm.RS384) || 097 alg.equals(JWSAlgorithm.ES384) || 098 alg.equals(JWSAlgorithm.PS384) ) { 099 100 mdAlg = "SHA-384"; 101 102 } else if (alg.equals(JWSAlgorithm.HS512) || 103 alg.equals(JWSAlgorithm.RS512) || 104 alg.equals(JWSAlgorithm.ES512) || 105 alg.equals(JWSAlgorithm.PS512) || 106 alg.equals(JWSAlgorithm.EdDSA) && Curve.Ed25519.equals(crv)) { 107 108 mdAlg = "SHA-512"; 109 110 } else { 111 // unsupported JWS alg 112 return null; 113 } 114 115 try { 116 return MessageDigest.getInstance(mdAlg); 117 118 } catch (NoSuchAlgorithmException e) { 119 120 // unsupported SHA-2 alg 121 return null; 122 } 123 } 124 125 126 /** 127 * Computes the SHA-2 claim value for the specified identifier. 128 * 129 * @param identifier The identifier, typically an authorisation code or 130 * an access token. Must not be {@code null}. 131 * @param alg The reference JWS algorithm. Must not be 132 * {@code null}. 133 * 134 * @return The matching (truncated to first half) SHA-2 claim value, 135 * or {@code null} if the JWS algorithm or its corresponding 136 * SHA-2 message digest are not supported. 137 * 138 * @deprecated Use {@link #computeValue(Identifier, JWSAlgorithm, Curve)} 139 * instead. 140 */ 141 @Deprecated 142 public static String computeValue(final Identifier identifier, 143 final JWSAlgorithm alg) { 144 145 return computeValue(identifier, alg, null); 146 } 147 148 149 /** 150 * Computes the SHA-2 claim value for the specified identifier. 151 * 152 * @param identifier The identifier, typically an authorisation code or 153 * an access token. Must not be {@code null}. 154 * @param alg The reference JWS algorithm. Must not be 155 * {@code null}. 156 * @param crv The JWK curve used with the JWS algorithm, 157 * {@code null} if not applicable. 158 * 159 * @return The matching (truncated to first half) SHA-2 claim value, 160 * or {@code null} if the JWS algorithm or its corresponding 161 * SHA-2 message digest are not supported. 162 */ 163 public static String computeValue(final Identifier identifier, 164 final JWSAlgorithm alg, 165 final Curve crv) { 166 167 MessageDigest md = getMessageDigestInstance(alg, crv); 168 169 if (md == null) 170 return null; 171 172 md.update(identifier.getValue().getBytes(StandardCharsets.US_ASCII)); 173 174 byte[] hash = md.digest(); 175 176 byte[] firstHalf = Arrays.copyOf(hash, hash.length / 2); 177 178 return Base64URL.encode(firstHalf).toString(); 179 } 180}