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}