All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
ee.sk.digidoc.UnsignedProperties Maven / Gradle / Ivy
/*
* UnsignedProperties.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 java.util.Vector;
import java.security.cert.X509Certificate;
import ee.sk.utils.ConvertUtils;
import ee.sk.utils.ConfigManager;
import ee.sk.digidoc.factory.BouncyCastleNotaryFactory;
import ee.sk.digidoc.factory.NotaryFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.apache.log4j.Logger;
/**
* Models the unsigned properties of
* a signature.
* @author Veiko Sinivee
* @version 1.0
*/
public class UnsignedProperties implements Serializable
{
private static final long serialVersionUID = 1L;
/** signature reference */
private Signature m_signature;
/** CompleteCertificateRefs object */
private CompleteCertificateRefs m_certRefs;
/** CompleteRevocationRefs object */
private CompleteRevocationRefs m_revRefs;
/** Notary object */
private Vector m_notaries;
private static Logger m_logger = Logger.getLogger(UnsignedProperties.class);
/**
* Creates new UsignedProperties
* Initializes everything to null
* @param sig signature reference
*/
public UnsignedProperties(Signature sig) {
m_signature = sig;
m_certRefs = null;
m_revRefs = null;
m_notaries = null;
}
/**
* Creates new UsignedProperties
* @param sig signature reference
* @param crefs responders cert digest & info
* @param rrefs OCSP response digest & info
*/
public UnsignedProperties(Signature sig, CompleteCertificateRefs crefs,
CompleteRevocationRefs rrefs)
throws DigiDocException
{
m_signature = sig;
setCompleteCertificateRefs(crefs);
setCompleteRevocationRefs(rrefs);
}
/**
* Accessor for completeCertificateRefs attribute
* @return value of completeCertificateRefs attribute
*/
public CompleteCertificateRefs getCompleteCertificateRefs() {
return m_certRefs;
}
/**
* Accessor for signature attribute
* @return value of signature attribute
*/
public Signature getSignature()
{
return m_signature;
}
/**
* Mutator for completeCertificateRefs attribute
* @param str new value for completeCertificateRefs attribute
* @throws DigiDocException for validation errors
*/
public void setCompleteCertificateRefs(CompleteCertificateRefs crefs)
throws DigiDocException
{
//ArrayList errs = crefs.validate();
//if(!errs.isEmpty())
// throw (DigiDocException)errs.get(0);
m_certRefs = crefs;
}
/**
* Accessor for completeRevocationRefs attribute
* @return value of completeRevocationRefs attribute
*/
public CompleteRevocationRefs getCompleteRevocationRefs() {
return m_revRefs;
}
/**
* Mutator for completeRevocationRefs attribute
* @param str new value for completeRevocationRefs attribute
* @throws DigiDocException for validation errors
*/
public void setCompleteRevocationRefs(CompleteRevocationRefs refs)
throws DigiDocException
{
//ArrayList errs = refs.validate();
//if(!errs.isEmpty())
// throw (DigiDocException)errs.get(0);
m_revRefs = refs;
}
/**
* Accessor for respondersCertificate attribute
* @return value of respondersCertificate attribute
*/
public X509Certificate getRespondersCertificate() {
X509Certificate cert = null;
if(m_signature != null) {
CertValue cval = m_signature.getCertValueOfType(CertValue.CERTVAL_TYPE_RESPONDER);
if(cval != null)
cert = cval.getCert();
}
return cert;
}
/**
* Mutator for respondersCertificate attribute
* @param cert new value for respondersCertificate attribute
* @throws DigiDocException for validation errors
*/
public void setRespondersCertificate(X509Certificate cert)
throws DigiDocException
{
if(m_signature != null && cert != null) {
CertValue cval = m_signature.getOrCreateCertValueOfType(CertValue.CERTVAL_TYPE_RESPONDER);
cval.setId(m_signature.getId() + "-RESPONDER_CERT");
cval.setCert(cert);
}
}
/**
* Helper method to validate a responders cert
* @param cert input data
* @return exception or null for ok
*/
private DigiDocException validateRespondersCertificate(X509Certificate cert)
{
DigiDocException ex = null;
return ex;
}
/**
* Get the n-th Notary object
* @param nIdx Notary index
* @return Notary object
*/
public Notary getNotaryById(int nIdx)
{
if(m_notaries != null && nIdx < m_notaries.size())
return (Notary)m_notaries.elementAt(nIdx);
else
return null;
}
/**
* Add a new Notary
* @param not Notary object
*/
public void addNotary(Notary not)
{
if(m_notaries == null)
m_notaries = new Vector();
m_notaries.add(not);
}
/**
* Count the number of Notary objects
* @return number of Notary objects
*/
public int countNotaries() { return (m_notaries != null) ? m_notaries.size() : 0; }
/**
* Accessor for notary attribute
* @return value of notary attribute
*/
public Notary getNotary() {
return getNotaryById(0);
}
/**
* Accessor for notary attribute
* @return value of notary attribute
*/
public Notary getLastNotary() {
return getNotaryById(countNotaries()-1);
}
/**
* Mutator for notary attribute
* @param str new value for notary attribute
* @throws DigiDocException for validation errors
*/
public void setNotary(Notary not)
throws DigiDocException
{
addNotary(not);
}
/**
* Verifies this confirmation
* @param sdoc parent doc object
* @return a possibly empty list of DigiDocException objects
*/
public ArrayList verify(SignedDoc sdoc)
{
ArrayList errs = new ArrayList();
// verify notary certs serial number using CompleteCertificateRefs
X509Certificate cert = getRespondersCertificate();
if(m_logger.isDebugEnabled())
m_logger.debug("Responders cert: " + cert.getSerialNumber() + " - " + cert.getSubjectDN().getName() +
" complete cert refs nr: " + m_certRefs.getCertSerial() + " - " + m_certRefs.getCertIssuer());
if(cert == null) {
errs.add(new DigiDocException(DigiDocException.ERR_RESPONDERS_CERT,
"No notarys certificate!", null));
return errs;
}
if(cert != null && !cert.getSerialNumber().equals(m_certRefs.getCertSerial()) &&
!m_signature.getSignedDoc().getFormat().equals(SignedDoc.FORMAT_BDOC)) {
errs.add(new DigiDocException(DigiDocException.ERR_RESPONDERS_CERT,
"Wrong notarys certificate: " + cert.getSerialNumber() + " ref: " + m_certRefs.getCertSerial(), null));
}
// verify notary certs digest using CompleteCertificateRefs
try {
if(!m_signature.getSignedDoc().getFormat().equals(SignedDoc.FORMAT_BDOC)) {
byte[] digest = SignedDoc.digestOfType(cert.getEncoded(), (m_signature.getSignedDoc().getFormat().
equals(SignedDoc.FORMAT_BDOC) ? SignedDoc.SHA256_DIGEST_TYPE : SignedDoc.SHA1_DIGEST_TYPE));
if(m_logger.isDebugEnabled())
m_logger.debug("Not cert calc hash: " + Base64Util.encode(digest, 0) +
" cert-ref hash: " + Base64Util.encode(m_certRefs.getCertDigestValue(), 0));
if(!SignedDoc.compareDigests(digest, m_certRefs.getCertDigestValue())) {
errs.add(new DigiDocException(DigiDocException.ERR_RESPONDERS_CERT,
"Notary certificates digest doesn't match!", null));
m_logger.error("Notary certificates digest doesn't match!");
}
}
} catch(DigiDocException ex) {
errs.add(ex);
} catch(Exception ex) {
errs.add(new DigiDocException(DigiDocException.ERR_RESPONDERS_CERT,
"Error calculating notary certificate digest!", null));
}
// verify notarys digest using CompleteRevocationRefs
try {
for(int i = 0; i < countNotaries(); i++) {
Notary not = getNotaryById(i);
byte[] ocspData = not.getOcspResponseData();
if(m_logger.isDebugEnabled())
m_logger.debug("OCSP value: " + not.getId() + " data: " + ((ocspData != null) ? ocspData.length : 0) + " bytes");
if(ocspData == null || ocspData.length == 0) {
errs.add(new DigiDocException(DigiDocException.ERR_NOTARY_DIGEST, "OCSP value is empty!", null));
continue;
}
OcspRef orf = m_revRefs.getOcspRefByUri("#" + not.getId());
if(m_logger.isDebugEnabled())
m_logger.debug("OCSP ref: " + ((orf != null) ? orf.getUri() : "NULL"));
if(orf == null) {
errs.add(new DigiDocException(DigiDocException.ERR_NOTARY_DIGEST, "No OCSP ref for uri: #" + not.getId(), null));
continue;
}
byte[] digest1 = SignedDoc.digestOfType(ocspData, (m_signature.getSignedDoc().getFormat().
equals(SignedDoc.FORMAT_BDOC) ? SignedDoc.SHA256_DIGEST_TYPE : SignedDoc.SHA1_DIGEST_TYPE));
byte[] digest2 = orf.getDigestValue();
if(m_logger.isDebugEnabled())
m_logger.debug("Check ocsp: " + not.getId() +
" calc hash: " + Base64Util.encode(digest1, 0) +
" refs-hash: " + Base64Util.encode(digest2, 0));
if(!SignedDoc.compareDigests(digest1, digest2)) {
errs.add(new DigiDocException(DigiDocException.ERR_NOTARY_DIGEST,
"Notarys digest doesn't match!", null));
m_logger.error("Notarys digest doesn't match!");
}
}
} catch(DigiDocException ex) {
errs.add(ex);
}
// verify notary status
try {
NotaryFactory notFac = ConfigManager.instance().getNotaryFactory();
for(int i = 0; i < countNotaries(); i++) {
Notary not = getNotaryById(i);
if(m_logger.isDebugEnabled())
m_logger.debug("Verify notray: " + not.getId() + " ocsp: " +
((not.getOcspResponseData() != null) ? not.getOcspResponseData().length : 0) +
" responder: " + not.getResponderId());
notFac.parseAndVerifyResponse(m_signature, not);
}
} catch(DigiDocException ex) {
errs.add(ex);
}
return errs;
}
/**
* Helper method to validate the whole
* UnsignedProperties object
* @return a possibly empty list of DigiDocException objects
*/
public ArrayList validate()
{
ArrayList errs = new ArrayList();
DigiDocException ex = null;
X509Certificate cert = getRespondersCertificate();
if(cert == null)
ex = validateRespondersCertificate(cert);
if(ex != null)
errs.add(ex);
ArrayList e = null;
if(m_certRefs != null) {
e = m_certRefs.validate();
if(!e.isEmpty())
errs.addAll(e);
}
if(m_revRefs != null) {
e = m_revRefs.validate();
if(!e.isEmpty())
errs.addAll(e);
}
// notary ???
return errs;
}
}