blob: a6944d97c58474a6ce226c25fd5d5776e9882b00 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.as2.api;
import java.security.Key;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.http.entity.ContentType;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.cms.CMSAlgorithm;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.SignerInfoGenerator;
import org.bouncycastle.cms.SignerInformation;
public class AS2SignedDataGenerator extends CMSSignedDataGenerator {
public static final Map<ASN1ObjectIdentifier, String> STANDARD_MICALGS;
static {
Map<ASN1ObjectIdentifier, String> stdMicAlgs = new HashMap<>();
stdMicAlgs.put(CMSAlgorithm.MD5, "md5");
stdMicAlgs.put(CMSAlgorithm.SHA1, "sha-1");
stdMicAlgs.put(CMSAlgorithm.SHA224, "sha-224");
stdMicAlgs.put(CMSAlgorithm.SHA256, "sha-256");
stdMicAlgs.put(CMSAlgorithm.SHA384, "sha-384");
stdMicAlgs.put(CMSAlgorithm.SHA512, "sha-512");
stdMicAlgs.put(CMSAlgorithm.GOST3411, "gostr3411-94");
stdMicAlgs.put(CMSAlgorithm.GOST3411_2012_256, "gostr3411-2012-256");
stdMicAlgs.put(CMSAlgorithm.GOST3411_2012_512, "gostr3411-2012-512");
STANDARD_MICALGS = Collections.unmodifiableMap(stdMicAlgs);
}
/**
* Signing algorithms for DSA keys in order of preference
*/
public static final String[] DSA_SIGNING_ALGORITHMS = {
"SHA512WITHDSA",
"SHA384WITHDSA",
"SHA256WITHDSA",
"SHA224WITHDSA",
"SHA1WITHDSA",
};
/**
* Signing algorithms for RSA keys in order of preference
*/
public static final String[] RSA_SIGNING_ALGORITHMS = {
"SHA512WITHRSA",
"SHA384WITHRSA",
"SHA256WITHRSA",
"SHA224WITHRSA",
"SHA1WITHRSA",
"MD5WITHRSA",
"MD2WITHRSA",
};
/**
* Signing algorithms for EC keys in order of preference
*/
public static final String[] EC_SIGNING_ALGORITHMS = {
"SHA512WITHECDSA",
"SHA384WITHECDSA",
"SHA256WITHECDSA",
"SHA224WITHECDSA",
"SHA1WITHECDSA",
};
public AS2SignedDataGenerator() {
}
/**
* Creates a <code>multipart/signed</code> content type containing the algorithms used by this generator.
*
* @param boundary - boundary to use to demarcate content.
* @return A <code>multipart/signed</code> content type
*/
public ContentType createMultipartSignedContentType(String boundary) {
StringBuffer header = new StringBuffer(AS2MediaType.MULTIPART_SIGNED);
header.append("; boundary=" + boundary);
Set<String> micAlgSet = new HashSet<>();
// Collect algorithm names used by pre-calculated signers
for (@SuppressWarnings("rawtypes")
Iterator it = _signers.iterator(); it.hasNext();) {
SignerInformation signer = (SignerInformation) it.next();
ASN1ObjectIdentifier digestOID = signer.getDigestAlgorithmID().getAlgorithm();
String micAlg = STANDARD_MICALGS.get(digestOID);
if (micAlg == null) {
micAlgSet.add("unknown");
} else {
micAlgSet.add(micAlg);
}
}
// Collect algorithm names used by signer generators
for (@SuppressWarnings("rawtypes")
Iterator it = signerGens.iterator(); it.hasNext();) {
SignerInfoGenerator signerInfoGen = (SignerInfoGenerator) it.next();
ASN1ObjectIdentifier digestOID = signerInfoGen.getDigestAlgorithm().getAlgorithm();
String micAlg = STANDARD_MICALGS.get(digestOID);
if (micAlg == null) {
micAlgSet.add("unknown");
} else {
micAlgSet.add(micAlg);
}
}
// Add algorithm names to multipart signed header.
int count = 0;
for (String micAlg : micAlgSet) {
if (count == 0) {
if (micAlgSet.size() != 1) {
header.append("; micalg=\"");
} else {
header.append("; micalg=");
}
} else {
header.append(',');
}
header.append(micAlg);
count++;
}
if (count != 0) {
if (micAlgSet.size() != 1) {
header.append('\"');
}
}
return ContentType.parse(header.toString());
}
public static String[] getSupportedSignatureAlgorithmNamesForKey(Key key) {
switch (key.getAlgorithm()) {
case "DSA":
return DSA_SIGNING_ALGORITHMS;
case "RSA":
return RSA_SIGNING_ALGORITHMS;
case "EC":
return EC_SIGNING_ALGORITHMS;
default:
return new String[0];
}
}
}