// Path: NetLicensingClient/src/main/java/com/labs64/netlicensing/domain/vo/Context.java
// public class Context extends GenericContext<String> {
// 
//     private String publicKey;
// 
//     public Context() {
//         super(String.class);
//     }
// 
//     public Context setBaseUrl(final String baseUrl) {
//         return (Context) this.setValue(Constants.BASE_URL, baseUrl);
//     }
// 
//     public String getBaseUrl() {
//         return getValue(Constants.BASE_URL);
//     }
// 
//     public Context setUsername(final String username) {
//         return (Context) this.setValue(Constants.USERNAME, username);
//     }
// 
//     public String getUsername() {
//         return getValue(Constants.USERNAME);
//     }
// 
//     public Context setPassword(final String password) {
//         return (Context) this.setValue(Constants.PASSWORD, password);
//     }
// 
//     public String getPassword() {
//         return getValue(Constants.PASSWORD);
//     }
// 
//     public Context setApiKey(final String apiKey) {
//         return (Context) this.setValue(Constants.Token.API_KEY, apiKey);
//     }
// 
//     public String getApiKey() {
//         return getValue(Constants.Token.API_KEY);
//     }
// 
//     public Context setSecurityMode(final SecurityMode securityMode) {
//         return (Context) this.setValue(Constants.SECURITY_MODE, securityMode.toString());
//     }
// 
//     public SecurityMode getSecurityMode() {
//         final String securityMode = getValue(Constants.SECURITY_MODE);
//         return securityMode != null ? SecurityMode.valueOf(securityMode) : null;
//     }
// 
//     public Context setVendorNumber(final String vendorNumber) {
//         return (Context) this.setValue(Constants.Vendor.VENDOR_NUMBER, vendorNumber);
//     }
// 
//     public String getVendorNumber() {
//         return getValue(Constants.Vendor.VENDOR_NUMBER);
//     }
// 
//     /**
//      * Add public key to be used for validate signed NetLicensing response.
//      *
//      * @param publicKey
//      *            client publicKey.
//      */
//     public void setPublicKey(final String publicKey) {
//         this.publicKey = publicKey;
//     }
// 
//     public String getPublicKey() {
//         return publicKey;
//     }
// 
// }
// 
// Path: NetLicensingClient/src/main/java/com/labs64/netlicensing/exception/BadSignatureException.java
// public class BadSignatureException extends NetLicensingException {
// 
//     private static final long serialVersionUID = -506669705393514519L;
// 
//     /**
//      * Construct a <code>ConversionException</code> with the specified detail message.
//      *
//      * @param msg
//      *            the detail message
//      */
//     public BadSignatureException(final String msg) {
//         super(msg);
//     }
// 
// }


import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import com.helger.xmldsig.XMLDSigValidationResult;
import com.labs64.netlicensing.domain.vo.Context;
import com.labs64.netlicensing.exception.BadSignatureException;
import com.labs64.netlicensing.schema.context.Netlicensing;
package com.labs64.netlicensing.util;






public class SignatureUtils {

    /**
     * Cleanse public key; replace CRLF and strip key headers
     * @param publicKey
     * @return cleansed public key
     */
    public static String cleansePublicKey(final String publicKey) {
        if (publicKey == null) {
            return publicKey;
        } else {
            return publicKey.replaceAll("\\n|\\r", "").replace("-----BEGIN PUBLIC KEY-----", "")
                    .replace("-----END PUBLIC KEY-----", "");
        }
    }

    /**
     * Read public key from the byte array
     * @param publicKey
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static PublicKey readPublicKey(final byte[] publicKey)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        final byte[] publicKeyByte = Base64.getDecoder().decode(publicKey);
        final X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyByte);
        final KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePublic(spec);
    }

    /**
     * Read public key from the string
     * @param publicKey
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static PublicKey readPublicKey(final String publicKey)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        return readPublicKey(publicKey.getBytes());
    }

    /**
     * Verify response signature.
     * @param context
     * @param response
     * @throws BadSignatureException
     */
// Path: NetLicensingClient/src/main/java/com/labs64/netlicensing/domain/vo/Context.java
// public class Context extends GenericContext<String> {
// 
//     private String publicKey;
// 
//     public Context() {
//         super(String.class);
//     }
// 
//     public Context setBaseUrl(final String baseUrl) {
//         return (Context) this.setValue(Constants.BASE_URL, baseUrl);
//     }
// 
//     public String getBaseUrl() {
//         return getValue(Constants.BASE_URL);
//     }
// 
//     public Context setUsername(final String username) {
//         return (Context) this.setValue(Constants.USERNAME, username);
//     }
// 
//     public String getUsername() {
//         return getValue(Constants.USERNAME);
//     }
// 
//     public Context setPassword(final String password) {
//         return (Context) this.setValue(Constants.PASSWORD, password);
//     }
// 
//     public String getPassword() {
//         return getValue(Constants.PASSWORD);
//     }
// 
//     public Context setApiKey(final String apiKey) {
//         return (Context) this.setValue(Constants.Token.API_KEY, apiKey);
//     }
// 
//     public String getApiKey() {
//         return getValue(Constants.Token.API_KEY);
//     }
// 
//     public Context setSecurityMode(final SecurityMode securityMode) {
//         return (Context) this.setValue(Constants.SECURITY_MODE, securityMode.toString());
//     }
// 
//     public SecurityMode getSecurityMode() {
//         final String securityMode = getValue(Constants.SECURITY_MODE);
//         return securityMode != null ? SecurityMode.valueOf(securityMode) : null;
//     }
// 
//     public Context setVendorNumber(final String vendorNumber) {
//         return (Context) this.setValue(Constants.Vendor.VENDOR_NUMBER, vendorNumber);
//     }
// 
//     public String getVendorNumber() {
//         return getValue(Constants.Vendor.VENDOR_NUMBER);
//     }
// 
//     /**
//      * Add public key to be used for validate signed NetLicensing response.
//      *
//      * @param publicKey
//      *            client publicKey.
//      */
//     public void setPublicKey(final String publicKey) {
//         this.publicKey = publicKey;
//     }
// 
//     public String getPublicKey() {
//         return publicKey;
//     }
// 
// }
// 
// Path: NetLicensingClient/src/main/java/com/labs64/netlicensing/exception/BadSignatureException.java
// public class BadSignatureException extends NetLicensingException {
// 
//     private static final long serialVersionUID = -506669705393514519L;
// 
//     /**
//      * Construct a <code>ConversionException</code> with the specified detail message.
//      *
//      * @param msg
//      *            the detail message
//      */
//     public BadSignatureException(final String msg) {
//         super(msg);
//     }
// 
// }


// Path: NetLicensingClient/src/main/java/com/labs64/netlicensing/util/SignatureUtils.java
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import com.helger.xmldsig.XMLDSigValidationResult;
import com.labs64.netlicensing.domain.vo.Context;
import com.labs64.netlicensing.exception.BadSignatureException;
import com.labs64.netlicensing.schema.context.Netlicensing;

package com.labs64.netlicensing.util;






public class SignatureUtils {

    /**
     * Cleanse public key; replace CRLF and strip key headers
     * @param publicKey
     * @return cleansed public key
     */
    public static String cleansePublicKey(final String publicKey) {
        if (publicKey == null) {
            return publicKey;
        } else {
            return publicKey.replaceAll("\\n|\\r", "").replace("-----BEGIN PUBLIC KEY-----", "")
                    .replace("-----END PUBLIC KEY-----", "");
        }
    }

    /**
     * Read public key from the byte array
     * @param publicKey
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static PublicKey readPublicKey(final byte[] publicKey)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        final byte[] publicKeyByte = Base64.getDecoder().decode(publicKey);
        final X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyByte);
        final KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePublic(spec);
    }

    /**
     * Read public key from the string
     * @param publicKey
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static PublicKey readPublicKey(final String publicKey)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        return readPublicKey(publicKey.getBytes());
    }

    /**
     * Verify response signature.
     * @param context
     * @param response
     * @throws BadSignatureException
     */
    public static void check(final Context context, final Netlicensing response) throws BadSignatureException {