summaryrefslogtreecommitdiff
path: root/bkucommon/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'bkucommon/src/main/java')
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/CMSHashDataInput.java67
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java39
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/Signature.java29
3 files changed, 118 insertions, 17 deletions
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/CMSHashDataInput.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/CMSHashDataInput.java
new file mode 100644
index 00000000..6aa37e15
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/CMSHashDataInput.java
@@ -0,0 +1,67 @@
+package at.gv.egiz.bku.slcommands.impl.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import at.gv.egiz.stal.HashDataInput;
+
+public class CMSHashDataInput implements HashDataInput {
+
+ private final static String DEFAULT_FILENAME = "SignatureData";
+ private final static String CMS_DEF_REFERENCE_ID = "Reference-1";
+
+ private byte[] data;
+ private String mimeType;
+
+ public CMSHashDataInput(byte[] data, String mimeType) {
+ this.data = data;
+ this.mimeType = mimeType;
+ }
+
+ @Override
+ public String getReferenceId() {
+ return CMS_DEF_REFERENCE_ID;
+ }
+
+ @Override
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ @Override
+ public String getEncoding() {
+ return null;
+ }
+
+ @Override
+ public String getFilename() {
+ String fileName = DEFAULT_FILENAME;
+ String extension = getExtensionForMimeType(mimeType);
+ if (extension != null)
+ fileName += extension;
+ return fileName;
+ }
+
+ @Override
+ public InputStream getHashDataInput() {
+ return new ByteArrayInputStream(data);
+ }
+ private static String getExtensionForMimeType(String mimeType) {
+ if (mimeType.equalsIgnoreCase("application/pdf")) {
+ return ".pdf";
+ }
+ else if (mimeType.equalsIgnoreCase("text/plain")) {
+ return ".txt";
+ }
+ else if (mimeType.equalsIgnoreCase("application/xml")) {
+ return ".xml";
+ }
+ else if (mimeType.equalsIgnoreCase("application/zip")) {
+ return ".zip";
+ }
+ else if (mimeType.equalsIgnoreCase("application/gzip")) {
+ return ".gz";
+ }
+ return null;
+ }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java
index cb7d9a7a..cdd8f111 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java
@@ -12,6 +12,7 @@ import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SignatureException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -21,6 +22,7 @@ import org.slf4j.LoggerFactory;
import at.gv.egiz.bku.slcommands.impl.xsect.STALSignatureException;
import at.gv.egiz.stal.ErrorResponse;
+import at.gv.egiz.stal.HashDataInput;
import at.gv.egiz.stal.STAL;
import at.gv.egiz.stal.STALRequest;
import at.gv.egiz.stal.STALResponse;
@@ -29,15 +31,22 @@ import at.gv.egiz.stal.SignResponse;
public class STALSecurityProvider extends IaikProvider {
- private final Logger log = LoggerFactory.getLogger(STALSecurityProvider.class);
+ private final static Logger log = LoggerFactory.getLogger(STALSecurityProvider.class);
- private String keyboxIdentifier;
+ private final static String ID_ECSIGTYPE = "1.2.840.10045.4";
+ @SuppressWarnings("unused")
+ private final static String ECDSA_PLAIN_SIGNATURES = "0.4.0.127.0.7.1.1.4.1";
+ private String keyboxIdentifier;
private STAL stal;
+ private List<HashDataInput> hashDataInput;
- public STALSecurityProvider(STAL stal, String keyboxIdentifier) {
+ public STALSecurityProvider(STAL stal, String keyboxIdentifier,
+ HashDataInput hashDataInput) {
this.keyboxIdentifier = keyboxIdentifier;
this.stal = stal;
+ this.hashDataInput = new ArrayList<HashDataInput>();
+ this.hashDataInput.add(hashDataInput);
}
/* (non-Javadoc)
@@ -50,12 +59,8 @@ public class STALSecurityProvider extends IaikProvider {
throws SignatureException, InvalidKeyException, NoSuchAlgorithmException {
log.debug("calculateSignatureFromSignedAttributes: " + signatureAlgorithm + ", " + digestAlgorithm);
- SignRequest signRequest = new SignRequest();
- signRequest.setKeyIdentifier(keyboxIdentifier);
- log.debug("SignedAttributes: " + Util.toBase64String(signedAttributes));
- signRequest.setSignedInfo(signedAttributes);
- signRequest.setSignedInfoIsRawData(true);
- signRequest.setSignatureMethod(privateKey.getAlgorithm());
+ SignRequest signRequest = getSTALSignRequest(keyboxIdentifier, signedAttributes,
+ privateKey.getAlgorithm(), hashDataInput);
log.debug("Sending STAL request ({})", privateKey.getAlgorithm());
List<STALResponse> responses =
@@ -79,11 +84,21 @@ public class STALSecurityProvider extends IaikProvider {
}
}
+ private static SignRequest getSTALSignRequest(String keyboxIdentifier,
+ byte[] signedAttributes, String signatureMethod, List<HashDataInput> hashDataInput) {
+ SignRequest signRequest = new SignRequest();
+ signRequest.setKeyIdentifier(keyboxIdentifier);
+ log.debug("SignedAttributes: " + Util.toBase64String(signedAttributes));
+ signRequest.setSignedInfo(signedAttributes);
+ signRequest.setSignedInfoIsCMSSignedAttributes(true);
+ signRequest.setSignatureMethod(signatureMethod);
+ signRequest.setHashDataInput(hashDataInput);
+ return signRequest;
+ }
+
private static byte[] wrapSignatureValue(byte[] sig, AlgorithmID sigAlgorithmID) {
String id = sigAlgorithmID.getAlgorithm().getID();
- // 0.4.0.127.0.7.1.1.4.1...: ecdsa-plain-signatures
- // 1.2.840.10045.4...: id-ecSigType
- if (id.startsWith("1.2.840.10045.4")) //X9.62 Format ECDSA signatures
+ if (id.startsWith(ID_ECSIGTYPE)) //X9.62 Format ECDSA signatures
{
//Wrap r and s in ASN.1 SEQUENCE
byte[] r = Arrays.copyOfRange(sig, 0, sig.length/2);
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 26de1052..307f0bfc 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
@@ -70,6 +70,7 @@ 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.stal.HashDataInput;
import at.gv.egiz.stal.STAL;
/**
@@ -79,6 +80,9 @@ import at.gv.egiz.stal.STAL;
* @author tkellner
*/
public class Signature {
+
+ public final static String ID_AA_ETS_MIMETYPE = "0.4.0.1733.2.1";
+
/**
* Logging facility.
*/
@@ -86,6 +90,8 @@ public class Signature {
private SignedData signedData;
private SignerInfo signerInfo;
+ private byte[] signedDocument;
+ private String mimeType;
private AlgorithmID signatureAlgorithm;
private AlgorithmID digestAlgorithm;
private String signatureAlgorithmURI;
@@ -95,13 +101,14 @@ public class Signature {
public Signature(CMSDataObjectRequiredMetaType dataObject, String structure,
X509Certificate signingCertificate, Date signingTime, boolean useStrongHash)
throws NoSuchAlgorithmException, CertificateEncodingException, CertificateException, X509ExtensionException, InvalidParameterException, CodingException {
- byte[] data = getContent(dataObject);
+ byte[] dataToBeSigned = getContent(dataObject);
int mode = structure.equalsIgnoreCase("enveloping") ? SignedData.IMPLICIT : SignedData.EXPLICIT;
- this.signedData = new SignedData(data, mode);
+ this.signedData = new SignedData(dataToBeSigned, mode);
setAlgorithmIDs(signingCertificate, useStrongHash);
createSignerInfo(signingCertificate);
setSignerCertificate(signingCertificate);
- setAttributes(dataObject.getMetaInfo().getMimeType(), signingCertificate, signingTime);
+ this.mimeType = dataObject.getMetaInfo().getMimeType();
+ setAttributes(this.mimeType, signingCertificate, signingTime);
}
private void createSignerInfo(X509Certificate signingCertificate) throws CertificateEncodingException, CertificateException {
@@ -130,7 +137,7 @@ public class Signature {
}
private void setMimeTypeAttrib(List<Attribute> attributes, String mimeType) {
- String oidStr = "0.4.0.1733.2.1";
+ String oidStr = ID_AA_ETS_MIMETYPE;
String name = "mime-type";
ObjectID mimeTypeOID = new ObjectID(oidStr, name);
@@ -167,6 +174,8 @@ public class Signature {
private byte[] getContent(CMSDataObjectRequiredMetaType dataObject) throws InvalidParameterException {
byte[] data = dataObject.getContent().getBase64Content();
+ this.signedDocument = data.clone();
+
ExcludedByteRangeType ebr = dataObject.getExcludedByteRange();
if (ebr == null)
return data;
@@ -176,6 +185,11 @@ public class Signature {
if (from > data.length || to > data.length || from > to)
throw new InvalidParameterException("ExcludeByteRange contains invalid data: [" +
from + "-" + to + "], Content length: " + data.length);
+
+ // Fill ExcludeByteRange with 0s for document to display in viewer
+ Arrays.fill(this.signedDocument, from, to+1, (byte)0);
+
+ // Remove ExcludeByteRange from data to be signed
byte[] first = null;
byte[] second = null;
if (from > 0)
@@ -264,8 +278,13 @@ public class Signature {
}
}
+ private HashDataInput getHashDataInput() {
+ return new CMSHashDataInput(signedDocument, mimeType);
+ }
+
public byte[] sign(STAL stal, String keyboxIdentifier) throws CMSException, CMSSignatureException, SLCommandException {
- signedData.setSecurityProvider(new STALSecurityProvider(stal, keyboxIdentifier));
+ signedData.setSecurityProvider(
+ new STALSecurityProvider(stal, keyboxIdentifier, getHashDataInput()));
setSignerInfo();
ContentInfo contentInfo = new ContentInfo(signedData);
return contentInfo.getEncoded();