ee.sk.digidoc.Reference Maven / Gradle / Ivy
/*
* Reference.java
* PROJECT: JDigiDoc
* DESCRIPTION: Digi Doc functions for creating
* and reading signed documents.
* 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.digidoc;
import java.io.Serializable;
import java.util.ArrayList;
import ee.sk.utils.ConfigManager;
import ee.sk.utils.ConvertUtils;
import java.io.ByteArrayOutputStream;
//A Inga <2008 aprill> BDOCiga seotud muudatused xml-is 1
import java.io.File;
//L Inga <2008 aprill> BDOCiga seotud muudatused xml-is 1
import java.io.IOException;
import org.apache.log4j.Logger;
/**
* Represents and XML-DSIG reference block
* that referrs to a particular piece of
* signed XML data and contains it's hash code.
* @author Veiko Sinivee
* @version 1.0
*/
public class Reference implements Serializable
{
private static final long serialVersionUID = 1L;
/** reference to parent SignedInfo object */
private SignedInfo m_sigInfo;
/** Id atribute value if set */
private String m_id;
/** URI to signed XML data */
private String m_uri;
/** selected digest algorithm */
private String m_digestAlgorithm;
/** digest data */
private byte[] m_digestValue;
/** transform algorithm */
private String m_transformAlgorithm;
/** type uri */
private String m_type;
private static Logger m_logger = Logger.getLogger(Reference.class);
/**
* Creates new Reference. Initializes
* everything to null
* @param sigInfo reference to parent SignedInfo object
*/
public Reference(SignedInfo sigInfo)
{
m_sigInfo = sigInfo;
m_uri = null;
m_id = null;
m_type = null;
m_digestAlgorithm = null;
m_digestValue = null;
m_transformAlgorithm = null;
}
/**
* Creates new Reference
* @param sigInfo reference to parent SignedInfo object
* @param uri reference uri pointing to signed XML data
* @param algorithm sigest algorithm identifier
* @param digest message digest data
* @param transform transform algorithm
* @throws DigiDocException for validation errors
*/
public Reference(SignedInfo sigInfo, String uri, String algorithm,
byte[] digest, String transform)
throws DigiDocException
{
m_sigInfo = sigInfo;
setUri(uri);
setDigestAlgorithm(algorithm);
setDigestValue(digest);
setTransformAlgorithm(transform);
}
/**
* Creates new Reference
* and initializes it with default
* values from the DataFile
* @param sigInfo reference to parent SignedInfo object
* @param df DataFile object
* @param digType digest type. Use null for default value
* @throws DigiDocException for validation errors
*/
public Reference(SignedInfo sigInfo, DataFile df, String digType)
throws DigiDocException
{
m_sigInfo = sigInfo;
String sDigType = digType;
if(digType == null)
sDigType = ConfigManager.instance().getDefaultDigestType(m_sigInfo.getSignature().getSignedDoc());
String sDigAlg = ConfigManager.digType2Alg(sDigType);
setDigestAlgorithm(sDigAlg);
// BDOC or plain xades
if(m_sigInfo.getSignature().getSignedDoc() != null &&
m_sigInfo.getSignature().getSignedDoc().getFormat() != null &&
m_sigInfo.getSignature().getSignedDoc().getFormat().equals(SignedDoc.FORMAT_BDOC) ) {
String s = df.getFileName();
int n1 = s.lastIndexOf(File.separator);
if(n1 > 0 && n1 < s.length())
s = s.substring(n1+1);
if(m_sigInfo.getSignature().getSignedDoc().getVersion().equals(SignedDoc.BDOC_VERSION_2_1))
setUri(s);
else
setUri("/" + s);
} else { // digidoc
if(df.getContentType().equals(DataFile.CONTENT_HASHCODE) ||
df.getContentType().equals(DataFile.CONTENT_EMBEDDED_BASE64)) {
setUri("#" + df.getId());
}
}
setDigestValue(df.getDigestValueOfType(sDigType));
}
/**
* Accessor for sigInfo attribute
* @return value of sigInfo attribute
*/
public SignedInfo getSignedInfo() {
return m_sigInfo;
}
/**
* Mutator for sigInfo attribute
* @param sigInfo new value for sigInfo attribute
*/
public void setSignedInfo(SignedInfo sigInfo)
{
m_sigInfo = sigInfo;
}
/**
* Creates new Reference
* and initializes it with default
* values from the SignedProperties
* @param sigInfo reference to parent SignedInfo object
* @param sp SignedProperties object
* @param digType digest type. Use null for default value
* @throws DigiDocException for validation errors
*/
public Reference(SignedInfo sigInfo, SignedProperties sp, String digType)
throws DigiDocException
{
m_sigInfo = sigInfo;
String sDigType = digType;
if(digType == null)
sDigType = ConfigManager.instance().getDefaultDigestType(m_sigInfo.getSignature().getSignedDoc());
String sDigAlg = ConfigManager.digType2Alg(sDigType);
setDigestAlgorithm(sDigAlg);
setUri(sp.getTarget() + "-SignedProperties");
setDigestValue(sp.calculateDigest());
setTransformAlgorithm(null);
}
/**
* Accessor for uri attribute
* @return value of uri attribute
*/
public String getUri() {
return m_uri;
}
/**
* Mutator for uri attribute
* @param str new value for uri attribute
* @throws DigiDocException for validation errors
*/
public void setUri(String str)
throws DigiDocException
{
DigiDocException ex = validateUri(str);
if(ex != null)
throw ex;
m_uri = str;
}
/**
* Helper method to validate a uri
* @param str input data
* @return exception or null for ok
*/
private DigiDocException validateUri(String str)
{
DigiDocException ex = null;
// check the uri somehow ???
if(str == null) {
ex = new DigiDocException(DigiDocException.ERR_REFERENCE_URI,"URI does not exists", null);
}
return ex;
}
/**
* 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 digestAlgorithm attribute
* @return value of digestAlgorithm attribute
*/
public String getDigestAlgorithm() {
return m_digestAlgorithm;
}
/**
* Mutator for digestAlgorithm attribute
* @param str new value for digestAlgorithm attribute
* @throws DigiDocException for validation errors
*/
public void setDigestAlgorithm(String str)
throws DigiDocException
{
DigiDocException ex = validateDigestAlgorithm(str);
if(ex != null)
throw ex;
m_digestAlgorithm = str;
}
/**
* Helper method to validate a digest algorithm
* @param str input data
* @return exception or null for ok
*/
private DigiDocException validateDigestAlgorithm(String str)
{
DigiDocException ex = null;
if(str == null ||
(!str.equals(SignedDoc.SHA1_DIGEST_ALGORITHM) &&
!str.equals(SignedDoc.SHA224_DIGEST_ALGORITHM) &&
!str.equals(SignedDoc.SHA256_DIGEST_ALGORITHM_1) &&
!str.equals(SignedDoc.SHA256_DIGEST_ALGORITHM_2) &&
!str.equals(SignedDoc.SHA512_DIGEST_ALGORITHM)))
ex = new DigiDocException(DigiDocException.ERR_DIGEST_ALGORITHM,
"Currently supports only SHA-1, SHA-256 or SHA-512 digest algorithm", null);
return ex;
}
/**
* Accessor for digestValue attribute
* @return value of digestValue attribute
*/
public byte[] getDigestValue() {
return m_digestValue;
}
/**
* Mutator for digestValue attribute
* @param data new value for digestValue attribute
* @throws DigiDocException for validation errors
*/
public void setDigestValue(byte[] data)
throws DigiDocException
{
DigiDocException ex = validateDigestValue(data);
if(ex != null)
throw ex;
m_digestValue = data;
}
/**
* Helper method to validate a digest value
* @param data input data
* @return exception or null for ok
*/
private DigiDocException validateDigestValue(byte[] data)
{
DigiDocException ex = null;
if(data == null ||
(data.length != SignedDoc.SHA1_DIGEST_LENGTH &&
data.length != SignedDoc.SHA224_DIGEST_LENGTH &&
data.length != SignedDoc.SHA256_DIGEST_LENGTH &&
data.length != SignedDoc.SHA512_DIGEST_LENGTH))
ex = new DigiDocException(DigiDocException.ERR_DIGEST_LENGTH,
"Invalid digest length", null);
return ex;
}
/**
* Accessor for transformAlgorithm attribute
* @return value of transformAlgorithm attribute
*/
public String getTransformAlgorithm() {
return m_transformAlgorithm;
}
/**
* Mutator for transformAlgorithm attribute.
* Currently supports only one transform which
* has to be digidoc detatched document transform
* or none at all.
* @param str new value for transformAlgorithm attribute
* @throws DigiDocException for validation errors
*/
public void setTransformAlgorithm(String str)
throws DigiDocException
{
DigiDocException ex = validateTransformAlgorithm(str);
if(ex != null)
throw ex;
m_transformAlgorithm = str;
}
/**
* Helper method to validate a transform algorithm
* @param str input data
* @return exception or null for ok
*/
private DigiDocException validateTransformAlgorithm(String str)
{
DigiDocException ex = null;
if(str != null && !str.equals(SignedDoc.DIGIDOC_DETATCHED_TRANSFORM) &&
!str.equals(SignedDoc.TRANSFORM_20001026) && !str.equals(SignedDoc.ENVELOPED_TRANSFORM))
ex = new DigiDocException(DigiDocException.ERR_TRANSFORM_ALGORITHM,
"Currently supports either no transforms or one detatched document transform", null);
return ex;
}
/**
* Accessor for Type attribute
* @return value of Type attribute
*/
public String getType() {
return m_type;
}
/**
* Mutator for Type attribute
* @param str new value for Type attribute
* @throws DigiDocException for validation errors
*/
public void setType(String str)
{
m_type = str;
}
/**
* Helper method to validate the whole
* Reference object
* @return a possibly empty list of DigiDocException objects
*/
public ArrayList validate()
{
ArrayList errs = new ArrayList();
DigiDocException ex = validateUri(m_uri);
if(ex != null)
errs.add(ex);
ex = validateDigestAlgorithm(m_digestAlgorithm);
if(ex != null)
errs.add(ex);
ex = validateDigestValue(m_digestValue);
if(ex != null)
errs.add(ex);
ex = validateTransformAlgorithm(m_transformAlgorithm);
if(ex != null)
errs.add(ex);
return errs;
}
}