001package com.nimbusds.oauth2.sdk.pkce; 002 003 004import java.security.MessageDigest; 005import java.security.NoSuchAlgorithmException; 006 007import com.nimbusds.jose.util.Base64URL; 008import com.nimbusds.oauth2.sdk.id.Identifier; 009 010 011/** 012 * Authorisation code challenge. 013 * 014 * <p>Related specifications: 015 * 016 * <ul> 017 * <li>Proof Key for Code Exchange by OAuth Public Clients (RFC 7636). 018 * </ul> 019 */ 020public class CodeChallenge extends Identifier { 021 022 023 /** 024 * Creates a new code challenge with the specified value. 025 * 026 * @param value The code challenge value. Must not be {@code null} or 027 * empty string. 028 */ 029 public CodeChallenge(final String value) { 030 super(value); 031 } 032 033 034 /** 035 * Computes the code challenge using the specified method and verifier. 036 * 037 * @param method The code challenge method. Must be supported and 038 * not {@code null}. 039 * @param codeVerifier The code verifier. Must not be {@code null}. 040 * 041 * @return The computed code challenge. 042 */ 043 public static CodeChallenge compute(final CodeChallengeMethod method, final CodeVerifier codeVerifier) { 044 045 if (CodeChallengeMethod.PLAIN.equals(method)) { 046 return new CodeChallenge(codeVerifier.getValue()); 047 } 048 049 if (CodeChallengeMethod.S256.equals(method)) { 050 051 MessageDigest md; 052 053 try { 054 md = MessageDigest.getInstance("SHA-256"); 055 } catch (NoSuchAlgorithmException e) { 056 throw new IllegalStateException(e.getMessage()); 057 } 058 059 byte[] hash = md.digest(codeVerifier.getValueBytes()); 060 061 return new CodeChallenge(Base64URL.encode(hash).toString()); 062 } 063 064 throw new IllegalArgumentException("Unsupported code challenge method: " + method); 065 } 066}