All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.xml.wss.impl.misc.SecurityUtil Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1997, 2022 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2022 Contributors to the Eclipse Foundation
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package com.sun.xml.wss.impl.misc;

import com.sun.xml.ws.security.Token;
import com.sun.xml.ws.security.opt.impl.JAXBFilterProcessingContext;
import com.sun.xml.ws.security.secext10.SecurityTokenReferenceType;
import com.sun.xml.wss.core.reference.SamlKeyIdentifier;
import com.sun.xml.wss.impl.PolicyTypeUtil;
import com.sun.xml.wss.impl.policy.mls.EncryptionPolicy;
import com.sun.xml.wss.impl.policy.mls.KeyBindingBase;
import com.sun.xml.wss.impl.policy.mls.WSSPolicy;

import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;
import javax.crypto.SecretKey;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import jakarta.xml.bind.JAXBElement;

import jakarta.xml.soap.SOAPElement;

import com.sun.xml.wss.XWSSecurityException;
import com.sun.xml.wss.impl.MessageConstants;
import com.sun.xml.wss.logging.LogDomainConstants;
import com.sun.xml.wss.logging.impl.crypto.LogStringsMessages;

import java.util.Random;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.HashMap;

import com.sun.xml.wss.impl.FilterProcessingContext;
import com.sun.xml.wss.impl.policy.mls.AuthenticationTokenPolicy;
import com.sun.xml.wss.impl.SecurableSoapMessage;
import com.sun.xml.wss.core.X509SecurityToken;
import com.sun.xml.wss.impl.WSSAssertion;

import org.apache.xml.security.algorithms.JCEMapper;
import com.sun.xml.ws.api.SOAPVersion;
import com.sun.xml.ws.api.security.secconv.client.SCTokenConfiguration;
import com.sun.xml.ws.api.security.trust.WSTrustException;
import com.sun.xml.ws.api.security.trust.client.IssuedTokenManager;
import com.sun.xml.ws.security.impl.IssuedTokenContextImpl;
import com.sun.xml.ws.security.IssuedTokenContext;
import com.sun.xml.wss.core.SecurityContextTokenImpl;
import com.sun.xml.wss.impl.policy.mls.SecureConversationTokenKeyBinding;
import com.sun.xml.wss.impl.policy.mls.IssuedTokenKeyBinding;

import com.sun.xml.ws.security.SecurityTokenReference;

import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Document;

import com.sun.xml.ws.security.trust.WSTrustConstants;

import com.sun.xml.ws.security.SecurityContextToken;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.cert.X509Certificate;
import javax.security.auth.Subject;
import com.sun.xml.ws.runtime.dev.SessionManager;
import com.sun.xml.ws.security.SecurityContextTokenInfo;
import com.sun.xml.ws.security.opt.impl.keyinfo.SecurityContextToken13;
import com.sun.xml.ws.security.secconv.impl.bindings.SecurityContextTokenType;
import com.sun.xml.ws.security.secconv.impl.client.DefaultSCTokenConfiguration;
import com.sun.xml.ws.security.trust.GenericToken;
import com.sun.xml.ws.security.trust.WSTrustElementFactory;
import com.sun.xml.wss.impl.XWSSecurityRuntimeException;
import com.sun.xml.wss.impl.policy.MLSPolicy;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * Utility class for the Encryption and Signature related methods
 * @author Ashutosh Shahi
 */
public class SecurityUtil {

    protected static final Logger log =  Logger.getLogger( LogDomainConstants.IMPL_CRYPTO_DOMAIN,
            LogDomainConstants.IMPL_CRYPTO_DOMAIN_BUNDLE);

    /** Creates a new instance of SecurityUtil */
    public SecurityUtil() {
    }

    public static SecretKey generateSymmetricKey(String algorithm) throws XWSSecurityException{
        try {

            //keyGen.init(168);//TODO-Venu
            String jceAlgo = JCEMapper.getJCEKeyAlgorithmFromURI(algorithm);
            //JCEMapper.translateURItoJCEID(algorithm);
            //
            if (MessageConstants.debug) {
                log.log(Level.FINEST, "JCE ALGORITHM "+ jceAlgo);
            }
            KeyGenerator keyGen = KeyGenerator.getInstance(jceAlgo);
            int length = 0;
            if(jceAlgo.startsWith("DES")){
                length = 168;
            }else{
                length = JCEMapper.getKeyLengthFromURI(algorithm);
            }
            keyGen.init(length);
            if (MessageConstants.debug) {
                log.log(Level.FINEST, "Algorithm key length "+length);
            }
            return keyGen.generateKey();
        } catch (Exception e) {
            log.log(Level.SEVERE,
                    LogStringsMessages.WSS_1208_FAILEDTO_GENERATE_RANDOM_SYMMETRICKEY(e.getMessage()),
                    new Object[] {e.getMessage()});
            throw new XWSSecurityException(
                    "Unable to Generate Symmetric Key", e);
        }
    }

    /**
     * Lookup method to get the Key Length based on algorithm
     * TODO: Not complete yet, need to add more algorithms
     * NOTE: This method should only be used for DerivedKeyTokenLengths
     **/
    public static int getLengthFromAlgorithm(String algorithm) {
        switch (algorithm) {
            case MessageConstants.AES_BLOCK_ENCRYPTION_192:
                return 24;
            case MessageConstants.AES_BLOCK_ENCRYPTION_256:
                return 32;
            case MessageConstants.AES_BLOCK_ENCRYPTION_128:
                return 16;
            case MessageConstants.TRIPLE_DES_BLOCK_ENCRYPTION:
                return 24;
            default:
                throw new UnsupportedOperationException("TODO: not yet implemented keyLength for" + algorithm);
        }
    }

    public static String generateUUID() {
        Random rnd = new Random();
        int intRandom = rnd.nextInt();
        return "XWSSGID-"+ System.currentTimeMillis() + intRandom;
    }

    public static byte[] P_SHA1(byte[] secret, byte[] seed
            ) throws Exception {

        byte[] aBytes, result;
        aBytes = seed;

        Mac hMac = Mac.getInstance("HMACSHA1");
        SecretKeySpec sKey = new SecretKeySpec(secret, "HMACSHA1");
        hMac.init(sKey);
        hMac.update(aBytes);
        aBytes = hMac.doFinal();
        hMac.reset();
        hMac.init(sKey);
        hMac.update(aBytes);
        hMac.update(seed);
        result = hMac.doFinal();

        return result;
    }

    public static byte[] P_SHA1(byte[] secret, byte[] seed,
            int requiredSize) throws NoSuchAlgorithmException, InvalidKeyException {
        Mac hMac = Mac.getInstance("HMACSHA1");
        SecretKeySpec sKey = new SecretKeySpec(secret, "HMACSHA1");

        byte[] result = new byte[requiredSize];
        int copied=0;

        byte[] aBytes = seed;
        hMac.init(sKey);
        hMac.update(aBytes);
        aBytes  = hMac.doFinal();

        int rounds = requiredSize/aBytes.length ;
        if(requiredSize % aBytes.length != 0)
            rounds++;

        for(int i = 0; i < rounds; i ++){

            hMac.reset();
            hMac.init(sKey);
            hMac.update(aBytes);
            hMac.update(seed);
            byte[] generated = hMac.doFinal();
            int takeBytes;
            if(i != rounds-1)
                takeBytes = generated.length;
            else
                takeBytes = requiredSize - (generated.length * i);
            System.arraycopy(generated, 0, result, copied, takeBytes);
            copied += takeBytes;
            hMac.init(sKey);
            hMac.update(aBytes);
            aBytes  = hMac.doFinal();
        }
        return result;
    }

    public static String getSecretKeyAlgorithm(String encryptionAlgo) {
        String encAlgo = JCEMapper.translateURItoJCEID(encryptionAlgo);
        if (encAlgo.startsWith("AES")) {
            return "AES";
        } else if (encAlgo.startsWith("DESede")) {
            return "DESede";
        } else if (encAlgo.startsWith("DES")) {
            return "DES";
        }
        return encAlgo;
    }

    public static void checkIncludeTokenPolicyOpt(JAXBFilterProcessingContext context,
            AuthenticationTokenPolicy.UsernameTokenBinding untBinding,
            String unTokenid) throws XWSSecurityException{
        try{
            //not sure if this check is required
            if (!untBinding.policyTokenWasSet()){
                return;
            }
            String itVersion = untBinding.getIncludeToken();
            if(KeyBindingBase.INCLUDE_ALWAYS_TO_RECIPIENT.equals(itVersion) ||
               KeyBindingBase.INCLUDE_ALWAYS_TO_RECIPIENT_VER2.equals(itVersion)){
                untBinding.setReferenceType(MessageConstants.DIRECT_REFERENCE_TYPE);
            } else {
                throw new UnsupportedOperationException(untBinding.getIncludeToken() + " not supported yet as IncludeToken policy");
            }
        } catch(Exception e){
            throw new XWSSecurityException(e);
        }
    }

    public static void checkIncludeTokenPolicy(FilterProcessingContext context,
            AuthenticationTokenPolicy.X509CertificateBinding certInfo,
            String x509id) throws XWSSecurityException{

        HashMap insertedX509Cache = context.getInsertedX509Cache();
        X509SecurityToken x509Token = (X509SecurityToken)insertedX509Cache.get(x509id);
        //SecurableSoapMessage secureMessage = context.getSecurableSoapMessage();

        try{
            if(x509Token == null){
                /*Token policyToken = certInfo.getPolicyToken();
                if (policyToken == null) {
                    return;
                }*/
                // no referencetype adjustment if it is not WS-SecurityPolicy
                if (!certInfo.policyTokenWasSet()){
                    return;
                }
                String itVersion = certInfo.getIncludeToken();
                if(KeyBindingBase.INCLUDE_ALWAYS_TO_RECIPIENT.equals(itVersion) ||
                   KeyBindingBase.INCLUDE_ALWAYS.equals(itVersion) ||
                   KeyBindingBase.INCLUDE_ALWAYS_TO_RECIPIENT_VER2.equals(itVersion) ||
                   KeyBindingBase.INCLUDE_ALWAYS_VER2.equals(itVersion)){
                    insertCertificate(context, certInfo, x509id);
                } else if(KeyBindingBase.INCLUDE_NEVER.equals(itVersion) ||
                          KeyBindingBase.INCLUDE_NEVER_VER2.equals(itVersion)){
                    WSSAssertion wssAssertion = context.getWSSAssertion();
                    if(MessageConstants.DIRECT_REFERENCE_TYPE.equals(certInfo.getReferenceType())){
                        if(wssAssertion != null){
                            if(wssAssertion.getRequiredProperties().contains(WSSAssertion.MUST_SUPPORT_REF_KEYIDENTIFIER))
                                certInfo.setReferenceType(MessageConstants.KEY_INDETIFIER_TYPE);
                            else if(wssAssertion.getRequiredProperties().contains(WSSAssertion.MUSTSUPPORT_REF_THUMBPRINT))
                                certInfo.setReferenceType(MessageConstants.THUMB_PRINT_TYPE);
                        } else {
                            // when wssAssertion is not set use KeyIdentifier
                            certInfo.setReferenceType(MessageConstants.KEY_INDETIFIER_TYPE);
                        }
                    }
                } else if(KeyBindingBase.INCLUDE_ONCE.equals(certInfo.getIncludeToken())){
                    throw new UnsupportedOperationException(KeyBindingBase.INCLUDE_ONCE + " not supported yet as IncludeToken policy");
                }
            }
        } catch(Exception e){
            throw new XWSSecurityException(e);
        }
    }

    public static void checkIncludeTokenPolicyOpt(JAXBFilterProcessingContext context,
            AuthenticationTokenPolicy.X509CertificateBinding certInfo,
            String x509id) throws XWSSecurityException{

        //SecurityHeaderElement she = context.getSecurityHeader().getChildElement(x509id);

        try{
            //if(she != null){
                /*Token policyToken = certInfo.getPolicyToken();
                if (policyToken == null) {
                    return;
                }*/
            // no referencetype adjustment if it is not WS-SecurityPolicy
            if (!certInfo.policyTokenWasSet()){
                return;
            }
            String itVersion = certInfo.getIncludeToken();
            if(KeyBindingBase.INCLUDE_ALWAYS_TO_RECIPIENT.equals(itVersion) ||
               KeyBindingBase.INCLUDE_ALWAYS.equals(itVersion) ||
               KeyBindingBase.INCLUDE_ALWAYS_TO_RECIPIENT_VER2.equals(itVersion) ||
               KeyBindingBase.INCLUDE_ALWAYS_VER2.equals(itVersion)){
                certInfo.setReferenceType(MessageConstants.DIRECT_REFERENCE_TYPE);
            } else if(KeyBindingBase.INCLUDE_NEVER.equals(itVersion) ||
                      KeyBindingBase.INCLUDE_NEVER_VER2.equals(itVersion)){
                WSSAssertion wssAssertion = context.getWSSAssertion();
                if(MessageConstants.DIRECT_REFERENCE_TYPE.equals(certInfo.getReferenceType())){
                    if(wssAssertion != null){
                        if (wssAssertion.getRequiredProperties().contains(WSSAssertion.MUSTSUPPORT_REF_ISSUER_SERIAL)) {
                            certInfo.setReferenceType(MessageConstants.X509_ISSUER_TYPE);
                        } else if(wssAssertion.getRequiredProperties().contains(WSSAssertion.MUSTSUPPORT_REF_THUMBPRINT)) {
                            certInfo.setReferenceType(MessageConstants.THUMB_PRINT_TYPE);
                        } else if(wssAssertion.getRequiredProperties().contains(WSSAssertion.MUST_SUPPORT_REF_KEYIDENTIFIER)) {
                            certInfo.setReferenceType(MessageConstants.KEY_INDETIFIER_TYPE);
                        }
                    } else {
                        // when wssAssertion is not set use Issuer Serial
                        certInfo.setReferenceType(MessageConstants.X509_ISSUER_TYPE);
                    }
                }
            } else if(KeyBindingBase.INCLUDE_ONCE.equals(certInfo.getIncludeToken())){
                throw new UnsupportedOperationException(KeyBindingBase.INCLUDE_ONCE + " not supported yet as IncludeToken policy");
            }
            //}
        } catch(Exception e){
            throw new XWSSecurityException(e);
        }
    }

    public static String  getWsuIdOrId(Element elem) throws XWSSecurityException {
        NamedNodeMap nmap = elem.getAttributes();
        Node attr = nmap.getNamedItem("Id");
        if (attr == null) {
            attr = nmap.getNamedItem("AssertionID");
            if (attr == null)
                attr = nmap.getNamedItem("ID");
            if (attr == null) {
                throw new XWSSecurityException("Issued Token Element does not have a Id or AssertionId attribute");
            }
        }
        return attr.getNodeValue();
    }


    public static void resolveSCT(FilterProcessingContext context, SecureConversationTokenKeyBinding sctBinding)
    throws XWSSecurityException {
        // resolve the ProofKey here and set it into ProcessingContext
        //String sctPolicyId = sctBinding.getPolicyToken().getTokenId();
        String sctPolicyId = sctBinding.getUUID();
        // this will work on the client side only
        //IssuedTokenContext ictx = context.getIssuedTokenContext(sctPolicyId);
        IssuedTokenContext ictx = null;
        String protocol = context.getWSSCVersion(context.getSecurityPolicyVersion());
        if(context.isClient()){
            String sctId = context.getSCPolicyIDtoSctIdMap(sctPolicyId);
            SCTokenConfiguration config = new DefaultSCTokenConfiguration(protocol, sctId, !context.isExpired(), !context.isInboundMessage());
            ictx =IssuedTokenManager.getInstance().createIssuedTokenContext(config, null);
            try{
                IssuedTokenManager.getInstance().getIssuedToken(ictx);
            }catch(WSTrustException e){
                throw new XWSSecurityException(e);
            }
        }
        if (ictx == null) {
            // this will work on the server side
            String sctId = "";
            if(context instanceof JAXBFilterProcessingContext){

                Object sctObject = context.getExtraneousProperty(MessageConstants.INCOMING_SCT);

                if (sctObject == null) {
                    throw new XWSSecurityException("SecureConversation Session Context not Found");
                }
                if(sctObject instanceof com.sun.xml.ws.security.opt.impl.incoming.SecurityContextToken){
                    com.sun.xml.ws.security.opt.impl.incoming.SecurityContextToken sct = (com.sun.xml.ws.security.opt.impl.incoming.SecurityContextToken)sctObject;
                    sctId = sct.getSCId();
                }else if(sctObject instanceof SecurityContextToken){
                    SecurityContextToken sct = (SecurityContextToken)sctObject;
                    sctId = sct.getIdentifier().toString();
                }
            } else{
                SecurityContextToken sct = (SecurityContextToken)context.getExtraneousProperty(MessageConstants.INCOMING_SCT);
                if (sct == null) {
                    throw new XWSSecurityException("SecureConversation Session Context not Found");
                }
                sctId = sct.getIdentifier().toString();
            }

            ictx = ((SessionManager)context.getExtraneousProperty("SessionManager")).getSecurityContext(sctId, !context.isExpired());
            java.net.URI identifier = null;
            String instance = null;
            String wsuId = null;

            SecurityContextToken sct = (SecurityContextToken)ictx.getSecurityToken();
            if (sct != null){
                identifier = sct.getIdentifier();
                instance = sct.getInstance();
                wsuId = sct.getWsuId();
            }else{
                SecurityContextTokenInfo sctInfo = ictx.getSecurityContextTokenInfo();
                identifier = java.net.URI.create(sctInfo.getIdentifier());
                instance = sctInfo.getInstance();
                wsuId = sctInfo.getExternalId();
            }

            ictx.setSecurityToken(WSTrustElementFactory.newInstance(protocol).createSecurityContextToken(identifier, instance, wsuId));
        }


        if (ictx == null) {
            throw new XWSSecurityException("SecureConversation Session Context not Found");
        } else {
            //System.out.println("SC Session located...");
        }
        //TODO: assuming only a single secure-conversation context
        context.setSecureConversationContext(ictx);
    }

    public static void resolveIssuedToken(FilterProcessingContext context, IssuedTokenKeyBinding itkb) throws XWSSecurityException {
        //resolve the ProofKey here and set it into ProcessingContext
        //String itPolicyId = itkb.getPolicyToken().getTokenId();
        String itPolicyId = itkb.getUUID();
        // this will work on the client side only
        IssuedTokenContext ictx = context.getIssuedTokenContext(itPolicyId);
        boolean clientSide = true;
        if (ictx == null) {
            // on the server we have the TrustCredentialHolder
            ictx = context.getTrustCredentialHolder();
            clientSide = false;
        }

        if (ictx == null) {
            throw new XWSSecurityException("Trust IssuedToken not Found");
        }
        if (ictx.getSecurityToken() instanceof GenericToken) {
            itkb.setRealId(((GenericToken)ictx.getSecurityToken()).getId());
        }

        context.setTrustContext(ictx);
        if (ictx.getProofKey() == null){
            //handle asymmetric issued key
            if (clientSide) {
                //TODO: change this later to use the Cert Alias
                X509Certificate cert = context.getSecurityEnvironment().getDefaultCertificate(
                        context.getExtraneousProperties());
                ictx.setRequestorCertificate(cert);
            }  else {
                //nothing todo on server side
            }
        }
    }

    public static void initInferredIssuedTokenContext(FilterProcessingContext wssContext, Token str, Key returnKey) {
        // new code which fixes issues with Brokered Trust.
        IssuedTokenContextImpl ictx = (IssuedTokenContextImpl)wssContext.getTrustCredentialHolder();
        if (ictx == null) {
            ictx = new IssuedTokenContextImpl();
        }

        ictx.setProofKey(returnKey.getEncoded());
        ictx.setUnAttachedSecurityTokenReference(str);
        wssContext.setTrustCredentialHolder(ictx);
    }

    public static boolean isEncryptedKey(SOAPElement elem) {

        return MessageConstants.XENC_ENCRYPTED_KEY_LNAME.equals(elem.getLocalName()) &&
                MessageConstants.XENC_NS.equals(elem.getNamespaceURI());
    }

    public static boolean isBinarySecret(SOAPElement elem) {
        return MessageConstants.BINARY_SECRET_LNAME.equals(elem.getLocalName()) &&
                WSTrustConstants.WST_NAMESPACE.equals(elem.getNamespaceURI());
    }
     @SuppressWarnings("unchecked")
    public static SecurityContextTokenImpl locateBySCTId(FilterProcessingContext context, String sctId) throws XWSSecurityException {

        Hashtable contextMap = context.getIssuedTokenContextMap();

        if (contextMap == null) {
            // print a warning here
            //System.out.println("context.getIssuedTokenContextMap was null.........");
            return null;
        }

        Iterator it = contextMap.entrySet().iterator();

        while (it.hasNext()) {
            Map.Entry entry = it.next();
            String tokenId = (String)entry.getKey();
            Object token = entry.getValue();
            if (token instanceof IssuedTokenContext) {
                Object securityToken = ((IssuedTokenContext)token).getSecurityToken();
                if (securityToken instanceof SecurityContextToken) {
                    SecurityContextToken ret = (SecurityContextToken)securityToken;
                    if (sctId.equals(ret.getIdentifier().toString())) {
                        return new SecurityContextTokenImpl(
                                context.getSOAPMessage().getSOAPPart(), ret.getIdentifier().toString(), ret.getInstance(), ret.getWsuId(), ret.getExtElements());
                    }
                }
            }
        }
        return null;
    }
     @SuppressWarnings("unchecked")
    public static void updateSamlVsKeyCache(SecurityTokenReference str, FilterProcessingContext ctx, Key symKey) {
        com.sun.xml.wss.core.ReferenceElement ref = ((com.sun.xml.wss.core.SecurityTokenReference)str).getReference();
        if (ref instanceof com.sun.xml.wss.core.reference.KeyIdentifier) {
            String assertionId = ((com.sun.xml.wss.core.reference.KeyIdentifier)ref).getReferenceValue();
            ctx.getSamlIdVSKeyCache().putIfAbsent(assertionId, symKey);
        }
    }
     @SuppressWarnings("unchecked")
    public static void updateSamlVsKeyCache(SecurityTokenReferenceType str, FilterProcessingContext ctx, Key symKey) {
        List list = str.getAny();
        for(int i=0;i() {
                     @Override
                     public Object run() {
                         to.getPrincipals().addAll(from.getPrincipals());
                         to.getPublicCredentials().addAll(from.getPublicCredentials());
                         to.getPrivateCredentials().addAll(from.getPrivateCredentials());
                         return null;
                     }
                 });
    }

     @SuppressWarnings("unchecked")
    public static Subject getSubject(final Map context){
        Subject otherPartySubject =
                (Subject)context.get(MessageConstants.AUTH_SUBJECT);
        if (otherPartySubject != null) {
            return otherPartySubject;
        }
        otherPartySubject =
                AccessController.doPrivileged(
                        new PrivilegedAction<>() {
                            @Override
                            public Subject run() {
                                Subject otherPartySubj = new Subject();
                                context.put(MessageConstants.AUTH_SUBJECT, otherPartySubj);
                                return otherPartySubj;
                            }
                        }
        );
        return otherPartySubject;
    }

    public static SecurityContextToken getSCT(SecurityContextToken sct, SOAPVersion version){
        if(sct instanceof com.sun.xml.ws.security.secconv.impl.wssx.bindings.SecurityContextTokenType){
            return new SecurityContextToken13(
                    (com.sun.xml.ws.security.secconv.impl.wssx.bindings.SecurityContextTokenType)sct,version);
        }else{
            return new com.sun.xml.ws.security.opt.impl.keyinfo.SecurityContextToken((SecurityContextTokenType)sct,version);
        }
    }
     @SuppressWarnings("unchecked")
    public static  void copy(Map p1, Map p2) {
        if (p2 == null || p1 == null) {
            return;
        }
        p1.putAll(p2);
    }

     public static Object newInstance(String className,
            ClassLoader classLoader, String spiName) {
        try {
            Class spiClass;
            if (classLoader == null) {
                spiClass = Class.forName(className);
            } else {
                spiClass = classLoader.loadClass(className);
            }
            return spiClass.getConstructor().newInstance();
        } catch (ClassNotFoundException x) {
            throw new XWSSecurityRuntimeException(
                    "The "  +  spiName + " :"  + className + " specified in META-INF/services was not found", x);
        } catch (Exception x) {
            throw new XWSSecurityRuntimeException(
                    "The "  +  spiName + " :"  + className + " specified in META-INF/services could not be instantiated", x);
        }
    }

     public static  Object loadSPIClass(URL url, String spiName) {
        InputStream is = null;
        if (url == null) {
            return null;
        }
        try {
            is = url.openStream();
            if(is!=null) {
                try {
                    BufferedReader rd =
                            new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
                    String factoryClassName = rd.readLine();
                    rd.close();
                    if (factoryClassName != null &&
                            ! "".equals(factoryClassName)) {
                        return newInstance(factoryClassName, Thread.currentThread().getContextClassLoader(), spiName);
                    }
                } catch (Exception e) {
                    throw new XWSSecurityRuntimeException(e);
                }
            }
        } catch (IOException e) {
            return null;
        }
        return null;
    }

    public static long toLong(String lng) throws XWSSecurityException {
        if (lng == null) {
            return 0;
        }
        long ret = 0L;
        try {
            ret = Long.parseLong(lng);
        }catch (Exception e) {
            log.log(Level.SEVERE, LogStringsMessages.WSS_0719_ERROR_GETTING_LONG_VALUE());
            throw new XWSSecurityException(e);
        }
        return ret;
    }
    public static String getKeyAlgo(String algo) {
        if (algo != null && algo.equals(MessageConstants.RSA_SHA256)) {
            return MessageConstants.RSA_SHA256_SIGMETHOD;
        } else if (algo != null && algo.equals(MessageConstants.RSA_SHA384)) {
            return MessageConstants.RSA_SHA384_SIGMETHOD;
        } else if (algo != null && algo.equals(MessageConstants.RSA_SHA512)) {
            return MessageConstants.RSA_SHA512_SIGMETHOD;
        } else {
            return MessageConstants.RSA_SHA1_SIGMETHOD;
        }
    }
}