001package com.nimbusds.jose.crypto;
002
003
004import net.jcip.annotations.ThreadSafe;
005
006import com.nimbusds.jose.DefaultJWSHeaderFilter;
007import com.nimbusds.jose.JOSEException;
008import com.nimbusds.jose.JWSHeaderFilter;
009import com.nimbusds.jose.JWSVerifier;
010import com.nimbusds.jose.ReadOnlyJWSHeader;
011import com.nimbusds.jose.util.Base64URL;
012
013
014/**
015 * Message Authentication Code (MAC) verifier of 
016 * {@link com.nimbusds.jose.JWSObject JWS objects}. This class is thread-safe.
017 *
018 * <p>Supports the following JSON Web Algorithms (JWAs):
019 *
020 * <ul>
021 *     <li>{@link com.nimbusds.jose.JWSAlgorithm#HS256}
022 *     <li>{@link com.nimbusds.jose.JWSAlgorithm#HS384}
023 *     <li>{@link com.nimbusds.jose.JWSAlgorithm#HS512}
024 * </ul>
025 *
026 * <p>Accepts all {@link com.nimbusds.jose.JWSHeader#getReservedParameterNames
027 * reserved JWS header parameters}. Modify the {@link #getJWSHeaderFilter
028 * header filter} properties to restrict the acceptable JWS algorithms and
029 * header parameters, or to allow custom JWS header parameters.
030 * 
031 * @author Vladimir Dzhuvinov
032 * @version $version$ (2013-05-16)
033 */
034@ThreadSafe
035public class MACVerifier extends MACProvider implements JWSVerifier {
036
037
038        /**
039         * The JWS header filter.
040         */
041        private final DefaultJWSHeaderFilter headerFilter;
042
043
044        /**
045         * Creates a new Message Authentication (MAC) verifier.
046         *
047         * @param sharedSecret The shared secret. Must not be {@code null}.
048         */
049        public MACVerifier(final byte[] sharedSecret) {
050
051                super(sharedSecret);
052
053                headerFilter = new DefaultJWSHeaderFilter(supportedAlgorithms());
054        }
055
056
057        /**
058         * Creates a new Message Authentication (MAC) verifier.
059         *
060         * @param sharedSecretString The shared secret as a UTF-8 encoded
061         *                           string. Must not be {@code null}.
062         */
063        public MACVerifier(final String sharedSecretString) {
064
065                super(sharedSecretString);
066
067                headerFilter = new DefaultJWSHeaderFilter(supportedAlgorithms());
068        }
069
070
071        @Override
072        public JWSHeaderFilter getJWSHeaderFilter() {
073
074                return headerFilter;
075        }
076
077
078        @Override
079        public boolean verify(final ReadOnlyJWSHeader header, 
080                              final byte[] signedContent, 
081                              final Base64URL signature)
082                throws JOSEException {
083
084                String jcaAlg = getJCAAlgorithmName(header.getAlgorithm());
085
086                byte[] hmac = HMAC.compute(jcaAlg, getSharedSecret(), signedContent);
087
088                Base64URL expectedSignature = Base64URL.encode(hmac);
089
090                if (expectedSignature.equals(signature)) {
091
092                        return true;
093
094                } else {
095
096                        return false;
097                }
098        }
099}