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.Charset; 022import java.security.MessageDigest; 023import java.security.NoSuchAlgorithmException; 024import java.util.Arrays; 025 026import com.nimbusds.jose.JWSAlgorithm; 027import com.nimbusds.jose.util.Base64URL; 028 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 /** 039 * Creates a new SHA-2 based claim with the specified value. 040 * 041 * @param value The claim value. Must not be {@code null}. 042 */ 043 protected HashClaim(final String value) { 044 045 super(value); 046 } 047 048 049 /** 050 * Gets the matching SHA-2 message digest for the specified JSON Web 051 * Signature (JWS) algorithm. 052 * 053 * @param alg The JWS algorithm. Must not be {@code null}. 054 * 055 * @return The SHA-2 message digest, {@code null} if the JWS algorithm 056 * or its corresponding SHA-2 message digest are not supported. 057 */ 058 public static MessageDigest getMessageDigestInstance(final JWSAlgorithm alg) { 059 060 String mdAlg; 061 062 if (alg.equals(JWSAlgorithm.HS256) || 063 alg.equals(JWSAlgorithm.RS256) || 064 alg.equals(JWSAlgorithm.ES256) || 065 alg.equals(JWSAlgorithm.PS256) ) { 066 067 mdAlg = "SHA-256"; 068 069 } else if (alg.equals(JWSAlgorithm.HS384) || 070 alg.equals(JWSAlgorithm.RS384) || 071 alg.equals(JWSAlgorithm.ES384) || 072 alg.equals(JWSAlgorithm.PS384) ) { 073 074 mdAlg = "SHA-384"; 075 076 } else if (alg.equals(JWSAlgorithm.HS512) || 077 alg.equals(JWSAlgorithm.RS512) || 078 alg.equals(JWSAlgorithm.ES512) || 079 alg.equals(JWSAlgorithm.PS512) ) { 080 081 mdAlg = "SHA-512"; 082 083 } else { 084 // unsupported JWS alg 085 return null; 086 } 087 088 try { 089 return MessageDigest.getInstance(mdAlg); 090 091 } catch (NoSuchAlgorithmException e) { 092 093 // unsupported SHA-2 alg 094 return null; 095 } 096 } 097 098 099 /** 100 * Computes the SHA-2 claim value for the specified identifier. 101 * 102 * @param identifier The identifier, typically an authorisation code or 103 * an access token. Must not be {@code null}. 104 * @param alg The reference JSON Web Signature (JWS) algorithm. 105 * Must not be {@code null}. 106 * 107 * @return The matching (truncated to first half) SHA-2 claim value, 108 * or {@code null} if the JWS algorithm or its corresponding 109 * SHA-2 message digest are not supported. 110 */ 111 public static String computeValue(final Identifier identifier, final JWSAlgorithm alg) { 112 113 MessageDigest md = getMessageDigestInstance(alg); 114 115 if (md == null) 116 return null; 117 118 md.update(identifier.getValue().getBytes(Charset.forName("US-ASCII"))); 119 120 byte[] hash = md.digest(); 121 122 byte[] firstHalf = Arrays.copyOf(hash, hash.length / 2); 123 124 return Base64URL.encode(firstHalf).toString(); 125 } 126}