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-03-22)
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        @Override
058        public JWSHeaderFilter getJWSHeaderFilter() {
059
060                return headerFilter;
061        }
062
063
064        @Override
065        public boolean verify(final ReadOnlyJWSHeader header, 
066                              final byte[] signedContent, 
067                              final Base64URL signature)
068                throws JOSEException {
069
070                String jcaAlg = getJCAAlgorithmName(header.getAlgorithm());
071
072                byte[] hmac = HMAC.compute(jcaAlg, getSharedSecret(), signedContent);
073
074                Base64URL expectedSignature = Base64URL.encode(hmac);
075
076                if (expectedSignature.equals(signature)) {
077
078                        return true;
079
080                } else {
081
082                        return false;
083                }
084        }
085}