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

ee.sk.xmlenc.EncryptedKey Maven / Gradle / Ivy

Go to download

A Java libray for manipulating Estonian digital signature container files DDOC and BDOC. Note that this library is deprecated. It is recommended to use the new DigiDoc4j library at https://github.com/open-eid/digidoc4j

There is a newer version: 3.12.1
Show newest version
/*
 * EncryptedKey.java
 * PROJECT: JDigiDoc
 * DESCRIPTION: some property of an encrypted data object 
 * AUTHOR:  Veiko Sinivee, S|E|B IT Partner Estonia
 *==================================================
 * Copyright (C) AS Sertifitseerimiskeskus
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * GNU Lesser General Public Licence is available at
 * http://www.gnu.org/copyleft/lesser.html
 *==================================================
 */
package ee.sk.xmlenc;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.SecureRandom;
import java.util.ArrayList;

import ee.sk.digidoc.Base64Util;
import ee.sk.digidoc.DigiDocException;
import ee.sk.utils.ConvertUtils;
import ee.sk.utils.ConfigManager;
import org.apache.log4j.Logger;

/**
 * Contains the data of an 
 * subelement of an  object
 * @author  Veiko Sinivee
 * @version 1.0
 */
public class EncryptedKey  implements Serializable
{
	private static final long serialVersionUID = 1L;
	/** Id atribute value (optional) */
	private String m_id;
	/** Recipient atribute value (optional) */
	private String m_recipient;
	/**  sublements atribute Algorithm value (required) */
	private String m_encryptionMethod;
	/**  sublements value (optional) */
	private String m_keyName;
	/**  sublements value (optional) */
	private String m_carriedKeyName;
    /** recipients certificate (required) */
    private X509Certificate m_recipientsCert;
    /** transport key data */
    private byte[] m_transportKeyData;
	/** log4j logger */
	private static Logger m_logger = Logger.getLogger(EncryptedKey.class);
        
    /**
     * Simplified constructor for  object that
     * takes only the required elements and sets the EncryptionMethod
     * to it's required value.
     * @param recvCert recipients certificate (required)
     * @throws DigiDocException for all errors
     */
    public EncryptedKey(X509Certificate recvCert)
    	throws DigiDocException
    {
		setId(null);
    	setRecipient(null);
    	setEncryptionMethod(EncryptedData.DENC_ENC_METHOD_RSA1_5);
    	setKeyName(null);
    	setCarriedKeyName(null);
    	setRecipientsCertificate(recvCert);
		m_transportKeyData = null;
    }    
    
	/**
	 * Default constructor for  object that
	 * takes initializes everything to default values.
	 * @throws DigiDocException for all errors
	 */
	public EncryptedKey()
	{
		m_logger = Logger.getLogger(EncryptedKey.class);
		setId(null);
		setRecipient(null);
		m_encryptionMethod = null; // invalid state!
		setKeyName(null);
		setCarriedKeyName(null);
		m_recipientsCert = null; // invalid value
		m_transportKeyData = null;
	}    
    
    /**
     * Constructor for  object
     * @param id Id atribute value (optional)
     * @param recipient Recipient atribute value (optional)
     * @param encryptionMethod  sublements atribute Algorithm value (required).
     * The only currently supported value is EncryptedData.DENC_ENC_METHOD_RSA1_5 !
     * @param keyName  sublements value (optional)
     * @param carriedKeyName  sublements value (optional)
     * @param recvCert recipients certificate (required)
     * @throws DigiDocException for all errors
     */
    public EncryptedKey(String id, String recipient, String encryptionMethod,
    		String keyName, String carriedKeyName, X509Certificate recvCert)
    	throws DigiDocException
    {
		setId(id);
    	setRecipient(recipient);
    	setEncryptionMethod(encryptionMethod);
    	setKeyName(keyName);
    	setCarriedKeyName(carriedKeyName);
    	setRecipientsCertificate(recvCert);
		m_transportKeyData = null;
    }

	/**
	 * Returns transport key data
	 * @return transport key data
	 */
	public byte[] getTransportKeyData() {
		return m_transportKeyData;
	}

    /**
     * Sets transport key data
     * @param key new transport key data
     */
    public void setTransportKeyData(byte[] key) {
		m_transportKeyData = key;
    }
    
    /**
     * Accessor for id attribute
     * @return value of Id attribute
     */
    public String getId() {
        return m_id;
    }
	
	/**
     * Mutator for Id attribute
     * @param str new value for Id attribute
     */    
    public void setId(String str) {
        m_id = str;
    }
    
    /**
     * Accessor for Recipient attribute
     * @return value of Recipient attribute
     */
    public String getRecipient() {
        return m_recipient;
    }
	
	/**
     * Mutator for Recipient attribute
     * @param str new value for Recipient attribute
     */    
    public void setRecipient(String str) {
    	m_recipient = str;
    }
    
    /**
     * Accessor for EncryptionMethod attribute
     * @return value of EncryptionMethod attribute
     */
    public String getEncryptionMethod() {
        return m_encryptionMethod;
    }
	
	/**
     * Mutator for EncryptionMethod attribute
     * @param str new value for EncryptionMethod attribute
     * @throws DigiDocException for validation errors
     */    
    public void setEncryptionMethod(String str) 
    	throws DigiDocException
    {
    	String str2 = str;
    	// fix this buggy URL problem
    	if(str2 != null && str2.equals(EncryptedData.DENC_ENC_METHOD_RSA1_5_BUGGY))
    		str2 = EncryptedData.DENC_ENC_METHOD_RSA1_5;
    	DigiDocException ex = validateEncryptionMethod(str2);
        if(ex != null)
            throw ex;
    	m_encryptionMethod = str2;
    }
    
    /**
     * Helper method to validate EncryptionMethod atribute
     * @param str input data
     * @return exception or null for ok
     */
    private DigiDocException validateEncryptionMethod(String str)
    {
        DigiDocException ex = null;
        if(str == null || !str.equals(EncryptedData.DENC_ENC_METHOD_RSA1_5))
            ex = new DigiDocException(DigiDocException.ERR_XMLENC_ENCKEY_ENCRYPTION_METHOD, 
                "EncryptionMethod atribute is required and currently the only supported value is: " 
            		+ EncryptedData.DENC_ENC_METHOD_RSA1_5, null);
        return ex;
    }
    
    /**
     * Accessor for KeyName attribute
     * @return value of KeyName attribute
     */
    public String getKeyName() {
        return m_keyName;
    }
	
	/**
     * Mutator for KeyName attribute
     * @param str new value for KeyName attribute
     */    
    public void setKeyName(String str) {
    	m_keyName = str;
    }
    
    /**
     * Accessor for CarriedKeyName attribute
     * @return value of CarriedKeyName attribute
     */
    public String getCarriedKeyName() {
        return m_carriedKeyName;
    }
	
	/**
     * Mutator for CarriedKeyName attribute
     * @param str new value for CarriedKeyName attribute
     */    
    public void setCarriedKeyName(String str) {
    	m_carriedKeyName = str;
    }

    /**
     * Accessor for RecipientsCertificate attribute
     * @return value of RecipientsCertificate attribute
     */
    public X509Certificate getRecipientsCertificate() {
        return m_recipientsCert;
    }
	
	/**
     * Mutator for RecipientsCertificate attribute
     * @param cert new value for RecipientsCertificate attribute
     * @throws DigiDocException for validation errors
     */    
    public void setRecipientsCertificate(X509Certificate cert) 
    	throws DigiDocException
    {
    	DigiDocException ex = validateRecipientsCertificate(cert);
        if(ex != null)
            throw ex;
        m_recipientsCert = cert;
    }

    /**
     * Helper method to validate RecipientsCertificate atribute
     * @param cert input data
     * @return exception or null for ok
     */
    private DigiDocException validateRecipientsCertificate(X509Certificate cert)
    {
        DigiDocException ex = null;
        if(cert == null)
            ex = new DigiDocException(DigiDocException.ERR_XMLENC_ENCKEY_CERT, 
                "RecipientsCertificate atribute is required", null);
        boolean keyUsages[] = cert.getKeyUsage();
        if(keyUsages == null || keyUsages.length < 2 || !keyUsages[2])
        	ex = new DigiDocException(DigiDocException.ERR_XMLENC_ENCKEY_CERT, 
                    "RecipientsCertificate is not suitable for encryption - keyEncipherment flag not set!", null);
        return ex;
    }
    

	/**
	 * Encrypts the transport key
	 * @param encData EncryptedData object containing the transport key  
	 * @throws DigiDocException for encryption errors
	 */
	public void encryptKey(EncryptedData encData)
		throws DigiDocException
	{
		// check key status first - nothing to encrypt?
		if(encData.getTransportKey() == null)
			 throw new DigiDocException(DigiDocException.ERR_XMLENC_KEY_STATUS,    
						 "Transport key has not been initialized!", null);	
		// check recipients cert - something to encrypt with?
		if(m_recipientsCert == null)
			 throw new DigiDocException(DigiDocException.ERR_XMLENC_KEY_STATUS,    
						 "Recipients certificate has not been initialized!", null);	
		// now try to encrypt the key and keep only the encrypted data
		try {
			Cipher alg = Cipher.getInstance(EncryptedData.DIGIDOC_KEY_ALOGORITHM, EncryptedData.DIGIDOC_SECURITY_PROVIDER_NAME);
			if(m_logger.isDebugEnabled())
				m_logger.debug("EncryptKey - algorithm: " + alg.getAlgorithm());
			//alg.init(Cipher.ENCRYPT_MODE, m_recipientsCert.getPublicKey());
			alg.init(Cipher.WRAP_MODE, m_recipientsCert.getPublicKey());
			//m_transportKeyData = alg.doFinal(m_transportKey.getEncoded());
			m_transportKeyData = alg.wrap(encData.getTransportKey());
			if(m_logger.isDebugEnabled())
				m_logger.debug("EncryptKey - data: " + ((m_transportKeyData == null) ? 0 : m_transportKeyData.length));
		} catch (Exception ex) {
					DigiDocException.handleException(ex, DigiDocException.ERR_XMLENC_KEY_ENCRYPT);
		}
	}


    
    /**
     * Converts the KeyInfo to XML form
     * @return XML representation of KeyInfo
     */
    public byte[] toXML()
        throws DigiDocException
    {
        ByteArrayOutputStream bos = 
                new ByteArrayOutputStream();
        try {
            bos.write(ConvertUtils.str2data(""));
            bos.write(ConvertUtils.str2data(""));            
			bos.write(ConvertUtils.str2data(""));            
            if(m_keyName != null) {
            	bos.write(ConvertUtils.str2data(""));
            	bos.write(ConvertUtils.str2data(m_keyName));
            	bos.write(ConvertUtils.str2data(""));                
            }
			bos.write(ConvertUtils.str2data(""));
			try {
                bos.write(ConvertUtils.str2data(Base64Util.encode(m_recipientsCert.getEncoded(), 64)));
            } catch(CertificateEncodingException ex) {
                DigiDocException.handleException(ex, DigiDocException.ERR_ENCODING);
            }
            bos.write(ConvertUtils.str2data(""));            
            bos.write(ConvertUtils.str2data(""));
            bos.write(ConvertUtils.str2data(""));
			if(m_transportKeyData != null) {
            	bos.write(ConvertUtils.str2data(Base64Util.encode(m_transportKeyData, 64)));            
            } else
				throw new DigiDocException(DigiDocException.ERR_XMLENC_KEY_STATUS,    
					"Invalid transport key status for transport!", null);     
            bos.write(ConvertUtils.str2data(""));            
            if(m_carriedKeyName != null) {
            	bos.write(ConvertUtils.str2data(""));
            	bos.write(ConvertUtils.str2data(m_carriedKeyName));
            	bos.write(ConvertUtils.str2data(""));                
            }
            bos.write(ConvertUtils.str2data(""));
         } catch(IOException ex) {
            DigiDocException.handleException(ex, DigiDocException.ERR_XML_CONVERT);
        }
        return bos.toByteArray();
    }
	
    /**
     * Helper method to validate the whole
     * EncryptedKey object
     * @return a possibly empty list of DigiDocException objects
     */
    public ArrayList validate()
    {
        ArrayList errs = new ArrayList();
        DigiDocException ex = validateEncryptionMethod(m_encryptionMethod);
        if(ex != null)
            errs.add(ex);
        ex = validateRecipientsCertificate(m_recipientsCert);
        if(ex != null)
            errs.add(ex);
        return errs;
    }

    /**
     * Returns the stringified form of KeyInfo
     * @return KeyInfo string representation
     */
    public String toString() {
        String str = null;
        try {
            str = new String(toXML());
        } catch(Exception ex) {}
        return str;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy