diff options
Diffstat (limited to 'bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/Signature.java')
-rw-r--r-- | bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/Signature.java | 702 |
1 files changed, 351 insertions, 351 deletions
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/Signature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/Signature.java index 4a94ca7f..97cae9a2 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/Signature.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/Signature.java @@ -1,351 +1,351 @@ -/* - * Copyright 2013 by Graz University of Technology, Austria - * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint - * initiative of the Federal Chancellery Austria and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - */ - - -package at.gv.egiz.bku.slcommands.impl.cms; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.security.InvalidParameterException; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -import javax.xml.crypto.dsig.DigestMethod; - -import org.apache.commons.lang.ArrayUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.w3._2000._09.xmldsig_.DigestMethodType; - -import at.buergerkarte.namespaces.securitylayer._1_2_3.CMSDataObjectOptionalMetaType; -import at.buergerkarte.namespaces.securitylayer._1_2_3.CMSDataObjectRequiredMetaType; -import at.buergerkarte.namespaces.securitylayer._1_2_3.DigestAndRefType; -import at.buergerkarte.namespaces.securitylayer._1_2_3.ExcludedByteRangeType; -import at.gv.egiz.bku.slcommands.impl.xsect.AlgorithmMethodFactory; -import at.gv.egiz.bku.slcommands.impl.xsect.AlgorithmMethodFactoryImpl; -import at.gv.egiz.bku.slcommands.impl.xsect.STALSignatureException; -import at.gv.egiz.bku.slexceptions.SLCommandException; -import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; -import at.gv.egiz.stal.HashDataInput; -import at.gv.egiz.stal.STAL; -import iaik.asn1.ASN1Object; -import iaik.asn1.CodingException; -import iaik.asn1.ObjectID; -import iaik.asn1.SEQUENCE; -import iaik.asn1.UTF8String; -import iaik.asn1.structures.AlgorithmID; -import iaik.asn1.structures.Attribute; -import iaik.asn1.structures.ChoiceOfTime; -import iaik.cms.CMSException; -import iaik.cms.CMSSignatureException; -import iaik.cms.CertificateIdentifier; -import iaik.cms.ContentInfo; -import iaik.cms.IssuerAndSerialNumber; -import iaik.cms.SignedData; -import iaik.cms.SignerInfo; -import iaik.smime.ess.ESSCertID; -import iaik.smime.ess.ESSCertIDv2; -import iaik.x509.X509ExtensionException; - -/** - * This class represents a CMS-Signature as to be created by the - * security layer command <code>CreateCMSSignatureRequest</code>. - * - * @author tkellner - */ -public class Signature { - - public final static String ID_AA_ETS_MIMETYPE = "0.4.0.1733.2.1"; - - /** - * Logging facility. - */ - private final Logger log = LoggerFactory.getLogger(Signature.class); - - protected SignedData signedData; - protected SignerInfo signerInfo; - protected byte[] signedDocument; - protected String mimeType; - protected AlgorithmID signatureAlgorithm; - protected AlgorithmID digestAlgorithm; - protected byte[] digestValue; - protected String signatureAlgorithmURI; - protected String digestAlgorithmURI; - protected ExcludedByteRangeType excludedByteRange; - private HashDataInput hashDataInput; - - -public Signature(CMSDataObjectOptionalMetaType dataObject, String structure, - X509Certificate signingCertificate, Date signingTime, URLDereferencer urlDereferencer, - boolean useStrongHash) - throws NoSuchAlgorithmException, CertificateEncodingException, - CertificateException, X509ExtensionException, InvalidParameterException, - CodingException, SLCommandException, IOException, CMSException { - int mode = structure.equalsIgnoreCase("enveloping") ? SignedData.IMPLICIT : SignedData.EXPLICIT; - if (dataObject.getContent() != null) { - byte[] dataToBeSigned = getContent(dataObject, urlDereferencer); - this.signedData = new SignedData(dataToBeSigned, mode); - if (dataObject.getMetaInfo() != null) { - this.mimeType = dataObject.getMetaInfo().getMimeType(); - } - - hashDataInput = new CMSHashDataInput(signedDocument, mimeType); - - } else { - DigestAndRefType digestAndRef = dataObject.getDigestAndRef(); - DigestMethodType digestMethod = digestAndRef.getDigestMethod(); - - hashDataInput = new ReferencedHashDataInput(dataObject.getMetaInfo().getMimeType(), urlDereferencer, - digestAndRef.getReference(), dataObject.getExcludedByteRange()); - - try { - digestAlgorithm = getAlgorithmID(digestMethod.getAlgorithm()); - } catch (URISyntaxException e) { - //TODO: choose proper execption - throw new NoSuchAlgorithmException(e); - } - digestValue = digestAndRef.getDigestValue(); - this.signedData = new SignedData(ObjectID.pkcs7_data); - } - setAlgorithmIDs(signingCertificate, useStrongHash); - createSignerInfo(signingCertificate); - setSignerCertificate(signingCertificate); - this.mimeType = dataObject.getMetaInfo().getMimeType(); - - setAttributes(this.mimeType, signingCertificate, signingTime); - } - - public Signature(CMSDataObjectRequiredMetaType dataObject, String structure, - X509Certificate signingCertificate, URLDereferencer urlDereferencer, - boolean useStrongHash) - throws NoSuchAlgorithmException, CertificateEncodingException, - CertificateException, X509ExtensionException, InvalidParameterException, - CodingException, SLCommandException, IOException { - byte[] dataToBeSigned = getContent(dataObject, urlDereferencer); - int mode = structure.equalsIgnoreCase("enveloping") ? SignedData.IMPLICIT : SignedData.EXPLICIT; - this.signedData = new SignedData(dataToBeSigned, mode); - setAlgorithmIDs(signingCertificate, useStrongHash); - createSignerInfo(signingCertificate); - setSignerCertificate(signingCertificate); - - - setAttributes(signingCertificate); - } - - - - private void createSignerInfo(X509Certificate signingCertificate) throws CertificateEncodingException, CertificateException { - iaik.x509.X509Certificate sigcert = - new iaik.x509.X509Certificate(signingCertificate.getEncoded()); - CertificateIdentifier signerIdentifier = - new IssuerAndSerialNumber(sigcert); - PrivateKey privateKey = new STALPrivateKey(signatureAlgorithmURI, digestAlgorithmURI); - signerInfo = new SignerInfo(signerIdentifier, digestAlgorithm, - signatureAlgorithm, privateKey); - } - - private void setSignerCertificate(X509Certificate signingCertificate) { - X509Certificate[] sigcerts = new X509Certificate[] { signingCertificate }; - signedData.addCertificates(sigcerts); - } - - private void setAttributes(String mimeType, X509Certificate signingCertificate, Date signingTime) throws CertificateException, NoSuchAlgorithmException, CodingException { - List<Attribute> attributes = new ArrayList<Attribute>(); - setMimeTypeAttrib(attributes, mimeType); - setContentTypeAttrib(attributes); - setSigningCertificateAttrib(attributes, signingCertificate); - if (signingTime != null) - setSigningTimeAttrib(attributes, signingTime); - Attribute[] attributeArray = attributes.toArray(new Attribute[attributes.size()]); - signerInfo.setSignedAttributes(attributeArray); - } - - private void setAttributes(X509Certificate signingCertificate) throws CertificateException, NoSuchAlgorithmException, CodingException { - List<Attribute> attributes = new ArrayList<Attribute>(); - setContentTypeAttrib(attributes); - setSigningCertificateAttrib(attributes, signingCertificate); - Attribute[] attributeArray = attributes.toArray(new Attribute[attributes.size()]); - signerInfo.setSignedAttributes(attributeArray); - } - - - - private void setMimeTypeAttrib(List<Attribute> attributes, String mimeType) { - String oidStr = ID_AA_ETS_MIMETYPE; - String name = "mime-type"; - ObjectID mimeTypeOID = new ObjectID(oidStr, name); - - Attribute mimeTypeAtt = new Attribute(mimeTypeOID, new ASN1Object[] {new UTF8String(mimeType)}); - attributes.add(mimeTypeAtt); - } - - private void setContentTypeAttrib(List<Attribute> attributes) { - Attribute contentType = new Attribute(ObjectID.contentType, new ASN1Object[] {ObjectID.cms_data}); - attributes.add(contentType); - } - - private void setSigningCertificateAttrib(List<Attribute> attributes, X509Certificate signingCertificate) throws CertificateException, NoSuchAlgorithmException, CodingException { - ObjectID id; - ASN1Object value = new SEQUENCE(); - if (digestAlgorithm.equals(AlgorithmID.sha1)) { - id = ObjectID.signingCertificate; - value.addComponent(new ESSCertID(signingCertificate, true).toASN1Object()); - } - else { - id = ObjectID.signingCertificateV2; - value.addComponent(new ESSCertIDv2(digestAlgorithm, signingCertificate, true).toASN1Object()); - } - ASN1Object signingCert = new SEQUENCE(); - signingCert.addComponent(value); - Attribute signingCertificateAttrib = new Attribute(id, new ASN1Object[] {signingCert}); - attributes.add(signingCertificateAttrib); - } - - private void setSigningTimeAttrib(List<Attribute> attributes, Date date) { - Attribute signingTime = new Attribute(ObjectID.signingTime, new ASN1Object[] {new ChoiceOfTime(date).toASN1Object()}); - attributes.add(signingTime); - } - - private byte[] getContent(CMSDataObjectOptionalMetaType dataObject, URLDereferencer urlDereferencer) - throws InvalidParameterException, SLCommandException, IOException { - byte[] data = dataObject.getContent().getBase64Content(); - if (data == null) { - String reference = dataObject.getContent().getReference(); - if (reference == null) - throw new SLCommandException(4003); - InputStream is = urlDereferencer.dereference(reference).getStream(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - for (int i = is.read(buffer); i > -1; i = is.read(buffer)) { - baos.write(buffer, 0, i); - } - data = baos.toByteArray(); - is.close(); - } - this.signedDocument = data.clone(); - - this.excludedByteRange = dataObject.getExcludedByteRange(); - if (this.excludedByteRange == null) - return data; - - int from = this.excludedByteRange.getFrom().intValue(); - int to = this.excludedByteRange.getTo().intValue(); - if (from > data.length || to > data.length || from > to) - throw new InvalidParameterException("ExcludedByteRange contains invalid data: [" + - from + "-" + to + "], Content length: " + data.length); - - // Fill ExcludedByteRange with 0s for document to display in viewer - Arrays.fill(this.signedDocument, from, to+1, (byte)0); - - // Remove ExcludedByteRange from data to be signed - byte[] first = null; - byte[] second = null; - if (from > 0) - first = Arrays.copyOfRange(data, 0, from); - if ((to + 1) < data.length) - second = Arrays.copyOfRange(data, to + 1, data.length); - data = ArrayUtils.addAll(first, second); - log.debug("ExcludedByteRange [" + from + "-" + to + "], Content length: " + data.length); - return data; - } - - private void setAlgorithmIDs(X509Certificate signingCertificate, boolean useStrongHash) throws NoSuchAlgorithmException { - AlgorithmMethodFactory amf = new AlgorithmMethodFactoryImpl(signingCertificate, useStrongHash); - signatureAlgorithmURI = amf.getSignatureAlgorithmURI(); - signatureAlgorithm = amf.getSignatureAlgorithmID(); - if (digestAlgorithm != null) { - if (AlgorithmID.sha1.equals(digestAlgorithm)) { - digestAlgorithmURI = DigestMethod.SHA1; - } else if (AlgorithmID.sha256.equals(digestAlgorithm)) { - digestAlgorithmURI = DigestMethod.SHA256; - } else if (AlgorithmID.sha512.equals(digestAlgorithm)) { - digestAlgorithmURI = DigestMethod.SHA512; - } else if (AlgorithmID.ripeMd160.equals(digestAlgorithm)) { - digestAlgorithmURI = DigestMethod.RIPEMD160; - } else { - throw new NoSuchAlgorithmException("Algorithm '" + digestAlgorithm + "' not supported."); - } - } else { - digestAlgorithmURI = amf.getDigestAlgorithmURI(); - digestAlgorithm = amf.getDigestAlgorithmID(); - } - } - - public HashDataInput getHashDataInput() { - - if (hashDataInput != null) { - return hashDataInput; - } else { - return new CMSHashDataInput(signedDocument, mimeType); - } - } - - - public byte[] sign(STAL stal, String keyboxIdentifier) throws CMSException, CMSSignatureException, SLCommandException { - STALSecurityProvider securityProvider = new STALSecurityProvider(stal, keyboxIdentifier, getHashDataInput(), this.excludedByteRange); - signedData.setSecurityProvider(securityProvider); - try { - signedData.addSignerInfo(signerInfo); - } catch (NoSuchAlgorithmException e) { - STALSignatureException stalSignatureException = securityProvider.getStalSignatureException(); - if (stalSignatureException != null) { - throw new SLCommandException(stalSignatureException.getErrorCode()); - } - throw new CMSSignatureException(e); - } - if (digestValue != null) { - try { - signedData.setMessageDigest(digestAlgorithm, digestValue); - } catch (NoSuchAlgorithmException e) { - throw new CMSSignatureException(e); - } - } - ContentInfo contentInfo = new ContentInfo(signedData); - return contentInfo.getEncoded(); - } - - protected AlgorithmID getAlgorithmID(String uri) throws URISyntaxException { - String oid = null; - URI urn = new URI(uri); - String scheme = urn.getScheme(); - if ("URN".equalsIgnoreCase(scheme)) { - String schemeSpecificPart = urn.getSchemeSpecificPart().toLowerCase(); - if (schemeSpecificPart.startsWith("oid:")) { - oid = schemeSpecificPart.substring(4, schemeSpecificPart.length()); -} - } - return new AlgorithmID(new ObjectID(oid)); - } -} - - +/*
+ * Copyright 2013 by Graz University of Technology, Austria
+ * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint
+ * initiative of the Federal Chancellery Austria and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egiz.bku.slcommands.impl.cms;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.InvalidParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import javax.xml.crypto.dsig.DigestMethod;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3._2000._09.xmldsig_.DigestMethodType;
+
+import at.buergerkarte.namespaces.securitylayer._1_2_3.CMSDataObjectOptionalMetaType;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.CMSDataObjectRequiredMetaType;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.DigestAndRefType;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.ExcludedByteRangeType;
+import at.gv.egiz.bku.slcommands.impl.xsect.AlgorithmMethodFactory;
+import at.gv.egiz.bku.slcommands.impl.xsect.AlgorithmMethodFactoryImpl;
+import at.gv.egiz.bku.slcommands.impl.xsect.STALSignatureException;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
+import at.gv.egiz.stal.HashDataInput;
+import at.gv.egiz.stal.STAL;
+import iaik.asn1.ASN1Object;
+import iaik.asn1.CodingException;
+import iaik.asn1.ObjectID;
+import iaik.asn1.SEQUENCE;
+import iaik.asn1.UTF8String;
+import iaik.asn1.structures.AlgorithmID;
+import iaik.asn1.structures.Attribute;
+import iaik.asn1.structures.ChoiceOfTime;
+import iaik.cms.CMSException;
+import iaik.cms.CMSSignatureException;
+import iaik.cms.CertificateIdentifier;
+import iaik.cms.ContentInfo;
+import iaik.cms.IssuerAndSerialNumber;
+import iaik.cms.SignedData;
+import iaik.cms.SignerInfo;
+import iaik.smime.ess.ESSCertID;
+import iaik.smime.ess.ESSCertIDv2;
+import iaik.x509.X509ExtensionException;
+
+/**
+ * This class represents a CMS-Signature as to be created by the
+ * security layer command <code>CreateCMSSignatureRequest</code>.
+ *
+ * @author tkellner
+ */
+public class Signature {
+
+ public final static String ID_AA_ETS_MIMETYPE = "0.4.0.1733.2.1";
+
+ /**
+ * Logging facility.
+ */
+ private final Logger log = LoggerFactory.getLogger(Signature.class);
+
+ protected SignedData signedData;
+ protected SignerInfo signerInfo;
+ protected byte[] signedDocument;
+ protected String mimeType;
+ protected AlgorithmID signatureAlgorithm;
+ protected AlgorithmID digestAlgorithm;
+ protected byte[] digestValue;
+ protected String signatureAlgorithmURI;
+ protected String digestAlgorithmURI;
+ protected ExcludedByteRangeType excludedByteRange;
+ private HashDataInput hashDataInput;
+
+
+public Signature(CMSDataObjectOptionalMetaType dataObject, String structure,
+ X509Certificate signingCertificate, Date signingTime, URLDereferencer urlDereferencer,
+ boolean useStrongHash)
+ throws NoSuchAlgorithmException, CertificateEncodingException,
+ CertificateException, X509ExtensionException, InvalidParameterException,
+ CodingException, SLCommandException, IOException, CMSException {
+ int mode = structure.equalsIgnoreCase("enveloping") ? SignedData.IMPLICIT : SignedData.EXPLICIT;
+ if (dataObject.getContent() != null) {
+ byte[] dataToBeSigned = getContent(dataObject, urlDereferencer);
+ this.signedData = new SignedData(dataToBeSigned, mode);
+ if (dataObject.getMetaInfo() != null) {
+ this.mimeType = dataObject.getMetaInfo().getMimeType();
+ }
+
+ hashDataInput = new CMSHashDataInput(signedDocument, mimeType);
+
+ } else {
+ DigestAndRefType digestAndRef = dataObject.getDigestAndRef();
+ DigestMethodType digestMethod = digestAndRef.getDigestMethod();
+
+ hashDataInput = new ReferencedHashDataInput(dataObject.getMetaInfo().getMimeType(), urlDereferencer,
+ digestAndRef.getReference(), dataObject.getExcludedByteRange());
+
+ try {
+ digestAlgorithm = getAlgorithmID(digestMethod.getAlgorithm());
+ } catch (URISyntaxException e) {
+ //TODO: choose proper execption
+ throw new NoSuchAlgorithmException(e);
+ }
+ digestValue = digestAndRef.getDigestValue();
+ this.signedData = new SignedData(ObjectID.pkcs7_data);
+ }
+ setAlgorithmIDs(signingCertificate, useStrongHash);
+ createSignerInfo(signingCertificate);
+ setSignerCertificate(signingCertificate);
+ this.mimeType = dataObject.getMetaInfo().getMimeType();
+
+ setAttributes(this.mimeType, signingCertificate, signingTime);
+ }
+
+ public Signature(CMSDataObjectRequiredMetaType dataObject, String structure,
+ X509Certificate signingCertificate, URLDereferencer urlDereferencer,
+ boolean useStrongHash)
+ throws NoSuchAlgorithmException, CertificateEncodingException,
+ CertificateException, X509ExtensionException, InvalidParameterException,
+ CodingException, SLCommandException, IOException {
+ byte[] dataToBeSigned = getContent(dataObject, urlDereferencer);
+ int mode = structure.equalsIgnoreCase("enveloping") ? SignedData.IMPLICIT : SignedData.EXPLICIT;
+ this.signedData = new SignedData(dataToBeSigned, mode);
+ setAlgorithmIDs(signingCertificate, useStrongHash);
+ createSignerInfo(signingCertificate);
+ setSignerCertificate(signingCertificate);
+
+
+ setAttributes(signingCertificate);
+ }
+
+
+
+ private void createSignerInfo(X509Certificate signingCertificate) throws CertificateEncodingException, CertificateException {
+ iaik.x509.X509Certificate sigcert =
+ new iaik.x509.X509Certificate(signingCertificate.getEncoded());
+ CertificateIdentifier signerIdentifier =
+ new IssuerAndSerialNumber(sigcert);
+ PrivateKey privateKey = new STALPrivateKey(signatureAlgorithmURI, digestAlgorithmURI);
+ signerInfo = new SignerInfo(signerIdentifier, digestAlgorithm,
+ signatureAlgorithm, privateKey);
+ }
+
+ private void setSignerCertificate(X509Certificate signingCertificate) {
+ X509Certificate[] sigcerts = new X509Certificate[] { signingCertificate };
+ signedData.addCertificates(sigcerts);
+ }
+
+ private void setAttributes(String mimeType, X509Certificate signingCertificate, Date signingTime) throws CertificateException, NoSuchAlgorithmException, CodingException {
+ List<Attribute> attributes = new ArrayList<Attribute>();
+ setMimeTypeAttrib(attributes, mimeType);
+ setContentTypeAttrib(attributes);
+ setSigningCertificateAttrib(attributes, signingCertificate);
+ if (signingTime != null)
+ setSigningTimeAttrib(attributes, signingTime);
+ Attribute[] attributeArray = attributes.toArray(new Attribute[attributes.size()]);
+ signerInfo.setSignedAttributes(attributeArray);
+ }
+
+ private void setAttributes(X509Certificate signingCertificate) throws CertificateException, NoSuchAlgorithmException, CodingException {
+ List<Attribute> attributes = new ArrayList<Attribute>();
+ setContentTypeAttrib(attributes);
+ setSigningCertificateAttrib(attributes, signingCertificate);
+ Attribute[] attributeArray = attributes.toArray(new Attribute[attributes.size()]);
+ signerInfo.setSignedAttributes(attributeArray);
+ }
+
+
+
+ private void setMimeTypeAttrib(List<Attribute> attributes, String mimeType) {
+ String oidStr = ID_AA_ETS_MIMETYPE;
+ String name = "mime-type";
+ ObjectID mimeTypeOID = new ObjectID(oidStr, name);
+
+ Attribute mimeTypeAtt = new Attribute(mimeTypeOID, new ASN1Object[] {new UTF8String(mimeType)});
+ attributes.add(mimeTypeAtt);
+ }
+
+ private void setContentTypeAttrib(List<Attribute> attributes) {
+ Attribute contentType = new Attribute(ObjectID.contentType, new ASN1Object[] {ObjectID.cms_data});
+ attributes.add(contentType);
+ }
+
+ private void setSigningCertificateAttrib(List<Attribute> attributes, X509Certificate signingCertificate) throws CertificateException, NoSuchAlgorithmException, CodingException {
+ ObjectID id;
+ ASN1Object value = new SEQUENCE();
+ if (digestAlgorithm.equals(AlgorithmID.sha1)) {
+ id = ObjectID.signingCertificate;
+ value.addComponent(new ESSCertID(signingCertificate, true).toASN1Object());
+ }
+ else {
+ id = ObjectID.signingCertificateV2;
+ value.addComponent(new ESSCertIDv2(digestAlgorithm, signingCertificate, true).toASN1Object());
+ }
+ ASN1Object signingCert = new SEQUENCE();
+ signingCert.addComponent(value);
+ Attribute signingCertificateAttrib = new Attribute(id, new ASN1Object[] {signingCert});
+ attributes.add(signingCertificateAttrib);
+ }
+
+ private void setSigningTimeAttrib(List<Attribute> attributes, Date date) {
+ Attribute signingTime = new Attribute(ObjectID.signingTime, new ASN1Object[] {new ChoiceOfTime(date).toASN1Object()});
+ attributes.add(signingTime);
+ }
+
+ private byte[] getContent(CMSDataObjectOptionalMetaType dataObject, URLDereferencer urlDereferencer)
+ throws InvalidParameterException, SLCommandException, IOException {
+ byte[] data = dataObject.getContent().getBase64Content();
+ if (data == null) {
+ String reference = dataObject.getContent().getReference();
+ if (reference == null)
+ throw new SLCommandException(4003);
+ InputStream is = urlDereferencer.dereference(reference).getStream();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ for (int i = is.read(buffer); i > -1; i = is.read(buffer)) {
+ baos.write(buffer, 0, i);
+ }
+ data = baos.toByteArray();
+ is.close();
+ }
+ this.signedDocument = data.clone();
+
+ this.excludedByteRange = dataObject.getExcludedByteRange();
+ if (this.excludedByteRange == null)
+ return data;
+
+ int from = this.excludedByteRange.getFrom().intValue();
+ int to = this.excludedByteRange.getTo().intValue();
+ if (from > data.length || to > data.length || from > to)
+ throw new InvalidParameterException("ExcludedByteRange contains invalid data: [" +
+ from + "-" + to + "], Content length: " + data.length);
+
+ // Fill ExcludedByteRange with 0s for document to display in viewer
+ Arrays.fill(this.signedDocument, from, to+1, (byte)0);
+
+ // Remove ExcludedByteRange from data to be signed
+ byte[] first = null;
+ byte[] second = null;
+ if (from > 0)
+ first = Arrays.copyOfRange(data, 0, from);
+ if ((to + 1) < data.length)
+ second = Arrays.copyOfRange(data, to + 1, data.length);
+ data = ArrayUtils.addAll(first, second);
+ log.debug("ExcludedByteRange [" + from + "-" + to + "], Content length: " + data.length);
+ return data;
+ }
+
+ protected void setAlgorithmIDs(X509Certificate signingCertificate, boolean useStrongHash) throws NoSuchAlgorithmException {
+ AlgorithmMethodFactory amf = new AlgorithmMethodFactoryImpl(signingCertificate, useStrongHash);
+ signatureAlgorithmURI = amf.getSignatureAlgorithmURI();
+ signatureAlgorithm = amf.getSignatureAlgorithmID();
+ if (digestAlgorithm != null) {
+ if (AlgorithmID.sha1.equals(digestAlgorithm)) {
+ digestAlgorithmURI = DigestMethod.SHA1;
+ } else if (AlgorithmID.sha256.equals(digestAlgorithm)) {
+ digestAlgorithmURI = DigestMethod.SHA256;
+ } else if (AlgorithmID.sha512.equals(digestAlgorithm)) {
+ digestAlgorithmURI = DigestMethod.SHA512;
+ } else if (AlgorithmID.ripeMd160.equals(digestAlgorithm)) {
+ digestAlgorithmURI = DigestMethod.RIPEMD160;
+ } else {
+ throw new NoSuchAlgorithmException("Algorithm '" + digestAlgorithm + "' not supported.");
+ }
+ } else {
+ digestAlgorithmURI = amf.getDigestAlgorithmURI();
+ digestAlgorithm = amf.getDigestAlgorithmID();
+ }
+ }
+
+ public HashDataInput getHashDataInput() {
+
+ if (hashDataInput != null) {
+ return hashDataInput;
+ } else {
+ return new CMSHashDataInput(signedDocument, mimeType);
+ }
+ }
+
+
+ public byte[] sign(STAL stal, String keyboxIdentifier) throws CMSException, CMSSignatureException, SLCommandException {
+ STALSecurityProvider securityProvider = new STALSecurityProvider(stal, keyboxIdentifier, getHashDataInput(), this.excludedByteRange);
+ signedData.setSecurityProvider(securityProvider);
+ try {
+ signedData.addSignerInfo(signerInfo);
+ } catch (NoSuchAlgorithmException e) {
+ STALSignatureException stalSignatureException = securityProvider.getStalSignatureException();
+ if (stalSignatureException != null) {
+ throw new SLCommandException(stalSignatureException.getErrorCode());
+ }
+ throw new CMSSignatureException(e);
+ }
+ if (digestValue != null) {
+ try {
+ signedData.setMessageDigest(digestAlgorithm, digestValue);
+ } catch (NoSuchAlgorithmException e) {
+ throw new CMSSignatureException(e);
+ }
+ }
+ ContentInfo contentInfo = new ContentInfo(signedData);
+ return contentInfo.getEncoded();
+ }
+
+ protected AlgorithmID getAlgorithmID(String uri) throws URISyntaxException {
+ String oid = null;
+ URI urn = new URI(uri);
+ String scheme = urn.getScheme();
+ if ("URN".equalsIgnoreCase(scheme)) {
+ String schemeSpecificPart = urn.getSchemeSpecificPart().toLowerCase();
+ if (schemeSpecificPart.startsWith("oid:")) {
+ oid = schemeSpecificPart.substring(4, schemeSpecificPart.length());
+}
+ }
+ return new AlgorithmID(new ObjectID(oid));
+ }
+}
+
+
|