| package org.bouncycastle.cms; |
| |
| import java.util.Date; |
| import java.util.Enumeration; |
| import java.util.Hashtable; |
| import java.util.Map; |
| |
| import org.bouncycastle.asn1.ASN1ObjectIdentifier; |
| import org.bouncycastle.asn1.DEROctetString; |
| import org.bouncycastle.asn1.DERSet; |
| import org.bouncycastle.asn1.cms.Attribute; |
| import org.bouncycastle.asn1.cms.AttributeTable; |
| import org.bouncycastle.asn1.cms.CMSAlgorithmProtection; |
| import org.bouncycastle.asn1.cms.CMSAttributes; |
| import org.bouncycastle.asn1.cms.Time; |
| import org.bouncycastle.asn1.x509.AlgorithmIdentifier; |
| |
| /** |
| * Default signed attributes generator. |
| */ |
| public class DefaultSignedAttributeTableGenerator |
| implements CMSAttributeTableGenerator |
| { |
| private final Hashtable table; |
| |
| /** |
| * Initialise to use all defaults |
| */ |
| public DefaultSignedAttributeTableGenerator() |
| { |
| table = new Hashtable(); |
| } |
| |
| /** |
| * Initialise with some extra attributes or overrides. |
| * |
| * @param attributeTable initial attribute table to use. |
| */ |
| public DefaultSignedAttributeTableGenerator( |
| AttributeTable attributeTable) |
| { |
| if (attributeTable != null) |
| { |
| table = attributeTable.toHashtable(); |
| } |
| else |
| { |
| table = new Hashtable(); |
| } |
| } |
| |
| /** |
| * Create a standard attribute table from the passed in parameters - this will |
| * normally include contentType, signingTime, messageDigest, and CMS algorithm protection. |
| * If the constructor using an AttributeTable was used, entries in it for contentType, signingTime, and |
| * messageDigest will override the generated ones. |
| * |
| * @param parameters source parameters for table generation. |
| * |
| * @return a filled in Hashtable of attributes. |
| */ |
| protected Hashtable createStandardAttributeTable( |
| Map parameters) |
| { |
| Hashtable std = copyHashTable(table); |
| |
| if (!std.containsKey(CMSAttributes.contentType)) |
| { |
| ASN1ObjectIdentifier contentType = ASN1ObjectIdentifier.getInstance( |
| parameters.get(CMSAttributeTableGenerator.CONTENT_TYPE)); |
| |
| // contentType will be null if we're trying to generate a counter signature. |
| if (contentType != null) |
| { |
| Attribute attr = new Attribute(CMSAttributes.contentType, |
| new DERSet(contentType)); |
| std.put(attr.getAttrType(), attr); |
| } |
| } |
| |
| if (!std.containsKey(CMSAttributes.signingTime)) |
| { |
| Date signingTime = new Date(); |
| Attribute attr = new Attribute(CMSAttributes.signingTime, |
| new DERSet(new Time(signingTime))); |
| std.put(attr.getAttrType(), attr); |
| } |
| |
| if (!std.containsKey(CMSAttributes.messageDigest)) |
| { |
| byte[] messageDigest = (byte[])parameters.get( |
| CMSAttributeTableGenerator.DIGEST); |
| Attribute attr = new Attribute(CMSAttributes.messageDigest, |
| new DERSet(new DEROctetString(messageDigest))); |
| std.put(attr.getAttrType(), attr); |
| } |
| |
| if (!std.contains(CMSAttributes.cmsAlgorithmProtect)) |
| { |
| Attribute attr = new Attribute(CMSAttributes.cmsAlgorithmProtect, new DERSet(new CMSAlgorithmProtection( |
| (AlgorithmIdentifier)parameters.get(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER), |
| CMSAlgorithmProtection.SIGNATURE, (AlgorithmIdentifier)parameters.get(CMSAttributeTableGenerator.SIGNATURE_ALGORITHM_IDENTIFIER)))); |
| std.put(attr.getAttrType(), attr); |
| } |
| |
| return std; |
| } |
| |
| /** |
| * @param parameters source parameters |
| * @return the populated attribute table |
| */ |
| public AttributeTable getAttributes(Map parameters) |
| { |
| return new AttributeTable(createStandardAttributeTable(parameters)); |
| } |
| |
| private static Hashtable copyHashTable(Hashtable paramsMap) |
| { |
| Hashtable newTable = new Hashtable(); |
| |
| Enumeration keys = paramsMap.keys(); |
| while (keys.hasMoreElements()) |
| { |
| Object key = keys.nextElement(); |
| newTable.put(key, paramsMap.get(key)); |
| } |
| |
| return newTable; |
| } |
| } |