HMACSignatureMethodsImpl.java 3.16 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.granite.crypto.CryptoException
 *  com.adobe.granite.crypto.CryptoSupport
 *  org.apache.oltu.commons.encodedtoken.TokenDecoder
 *  org.apache.oltu.jose.jws.signature.SignatureMethod
 *  org.apache.oltu.jose.jws.signature.SigningKey
 *  org.apache.oltu.jose.jws.signature.VerifyingKey
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.oauth.jwt.impl;

import com.adobe.granite.crypto.CryptoException;
import com.adobe.granite.crypto.CryptoSupport;
import com.adobe.granite.oauth.jwt.impl.SymmetricKey;
import org.apache.oltu.commons.encodedtoken.TokenDecoder;
import org.apache.oltu.jose.jws.signature.SignatureMethod;
import org.apache.oltu.jose.jws.signature.SigningKey;
import org.apache.oltu.jose.jws.signature.VerifyingKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/*
 * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
 */
public class HMACSignatureMethodsImpl
implements SignatureMethod<SymmetricKey, SymmetricKey> {
    private final Logger logger = LoggerFactory.getLogger(HMACSignatureMethodsImpl.class);
    private CryptoSupport cryptoSupport;

    public HMACSignatureMethodsImpl(CryptoSupport cryptoSupport) {
        this.cryptoSupport = cryptoSupport;
    }

    public String getAlgorithm() {
        return "HS256";
    }

    public String calculate(String header, String payload, SymmetricKey signingKey) {
        this.logger.debug("calculate: calculate signature for header {} and payload {}", (Object)header, (Object)payload);
        try {
            StringBuilder sb = new StringBuilder();
            sb.append(header).append(".").append(payload);
            String stringToSign = sb.toString();
            byte[] bytes = stringToSign.getBytes();
            if (signingKey == null || signingKey.getKey() == null) {
                this.logger.debug("calculate: empty key, using the system hmac key");
                return TokenDecoder.base64Encode((byte[])this.cryptoSupport.hmac_sha256(bytes));
            }
            return TokenDecoder.base64Encode((byte[])this.cryptoSupport.hmac_sha256(signingKey.getKey(), bytes));
        }
        catch (CryptoException e) {
            throw new RuntimeException("failed while calculating the signature", (Throwable)e);
        }
    }

    public boolean verify(String signature, String header, String payload, SymmetricKey verifyingKey) {
        this.logger.debug("verify: verify signature for header {} and payload {}", (Object)header, (Object)payload);
        String signed = this.calculate(header, payload, verifyingKey);
        return HMACSignatureMethodsImpl.compareSecure(signed, signature);
    }

    private static boolean compareSecure(String a, String b) {
        if (a == null || b == null) {
            return a == null && b == null;
        }
        int len = a.length();
        if (len != b.length()) {
            return false;
        }
        if (len == 0) {
            return true;
        }
        int bits = 0;
        for (int i = 0; i < len; ++i) {
            bits |= a.charAt(i) ^ b.charAt(i);
        }
        return bits == 0;
    }
}