From 54aa4703e3d66c5b1a63b8d925fd4c9c1766687c Mon Sep 17 00:00:00 2001 From: clemenso Date: Wed, 28 Jan 2009 19:40:11 +0000 Subject: activation git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@291 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../egiz/idlink/CompressedIdentityLinkFactory.java | 800 ++++++++++----------- .../at/gv/egiz/idlink/IdentityLinkFactory.java | 6 +- .../java/at/gv/egiz/marshal/MarshallerFactory.java | 52 ++ .../gv/egiz/marshal/NamespacePrefixMapperImpl.java | 86 +++ .../gv/egiz/xades/QualifyingPropertiesFactory.java | 418 +++++------ 5 files changed, 750 insertions(+), 612 deletions(-) create mode 100644 utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java create mode 100644 utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java (limited to 'utils/src') diff --git a/utils/src/main/java/at/gv/egiz/idlink/CompressedIdentityLinkFactory.java b/utils/src/main/java/at/gv/egiz/idlink/CompressedIdentityLinkFactory.java index 5f4e5d92..31e5163a 100644 --- a/utils/src/main/java/at/gv/egiz/idlink/CompressedIdentityLinkFactory.java +++ b/utils/src/main/java/at/gv/egiz/idlink/CompressedIdentityLinkFactory.java @@ -14,403 +14,403 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package at.gv.egiz.idlink; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.security.PublicKey; -import java.security.cert.X509Certificate; -import java.util.List; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.PropertyException; -import javax.xml.bind.Unmarshaller; -import javax.xml.transform.Source; -import javax.xml.transform.dom.DOMResult; - -import org.w3._2000._09.xmldsig_.KeyValueType; -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import at.buergerkarte.namespaces.personenbindung._20020506_.CompressedIdentityLinkType; -import at.gv.e_government.reference.namespace.persondata._20020228_.AbstractPersonType; -import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType; -import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType; -import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType; -import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value; -import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType.FamilyName; -import at.gv.egiz.idlink.ans1.CitizenPublicKey; -import at.gv.egiz.idlink.ans1.IdentityLink; -import at.gv.egiz.idlink.ans1.PersonData; -import at.gv.egiz.idlink.ans1.PhysicalPersonData; -import at.gv.egiz.xmldsig.KeyTypeNotSupportedException; -import at.gv.egiz.xmldsig.KeyValueFactory; - -public class CompressedIdentityLinkFactory { - - /** - * The instance returned by {@link #getInstance()}. - */ - private static CompressedIdentityLinkFactory instance; - - /** - * The JAXBContext. - */ - private static JAXBContext jaxbContext; - - /** - * The KeyValueFactory. - */ - private static KeyValueFactory keyValueFactory; - - /** - * Get an instance of this CompressedIdentityLinkFactory. - * - * @return an instance of this CompressedIdentityLinkFactory - */ - public synchronized static CompressedIdentityLinkFactory getInstance() { - if (instance == null) { - instance = new CompressedIdentityLinkFactory(); - } - return instance; - } - - /** - * Private constructor. - */ - private CompressedIdentityLinkFactory() { - - keyValueFactory = new KeyValueFactory(); - - StringBuffer packageNames = new StringBuffer(); - packageNames.append(at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory.class.getPackage().getName()); - packageNames.append(":"); - packageNames.append(org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName()); - packageNames.append(":"); - packageNames.append(org.w3._2001._04.xmldsig_more_.ObjectFactory.class.getPackage().getName()); - packageNames.append(":"); - packageNames.append(at.buergerkarte.namespaces.personenbindung._20020506_.ObjectFactory.class.getPackage().getName()); - - try { - jaxbContext = JAXBContext.newInstance(packageNames.toString()); - } catch (JAXBException e) { - // we should not get an JAXBException initializing the JAXBContext - throw new RuntimeException(e); - } - - } - - public IdentityLink createIdLink(CompressedIdentityLinkType compressedIdentityLinkType) { - - // IssuerTemplate - String issuerTemplate = compressedIdentityLinkType.getIssuerTemplate(); - - // AssertionId - String assertionID = compressedIdentityLinkType.getAssertionID(); - - // IssueInstant - String issueInstant = compressedIdentityLinkType.getIssueInstant(); - - AbstractPersonType personDataType = compressedIdentityLinkType.getPersonData(); - - String baseId = null; - - List identifications = personDataType.getIdentification(); - for (IdentificationType identificationType : identifications) { - String type = identificationType.getType(); - if ("urn:publicid:gv.at:baseid".equals(type)) { - baseId = identificationType.getValue().getValue(); - } - } - - String givenName = null; - String familyName = null; - String dateOfBirth = null; - - if (personDataType instanceof PhysicalPersonType) { - PhysicalPersonType physicalPersonType = (PhysicalPersonType) personDataType; - PersonNameType name = physicalPersonType.getName(); - List givenNames = name.getGivenName(); - if (!givenNames.isEmpty()) { - givenName = givenNames.get(0); - } - List familyNames = name.getFamilyName(); - if (!familyNames.isEmpty()) { - familyName = familyNames.get(0).getValue(); - } - dateOfBirth = physicalPersonType.getDateOfBirth(); - } - - PhysicalPersonData physicalPersonData = new PhysicalPersonData(baseId, givenName, familyName, dateOfBirth); - PersonData personData = new PersonData(physicalPersonData); - - int numKeys = compressedIdentityLinkType.getCitizenPublicKey().size(); - CitizenPublicKey[] citizenPublicKeys = new CitizenPublicKey[numKeys]; - for (int i = 0; i < numKeys;) { - citizenPublicKeys[i] = new CitizenPublicKey(++i); - } - - byte[] signatureValue = compressedIdentityLinkType.getSignatureValue(); - byte[] referenceDigest = compressedIdentityLinkType.getReferenceDigest(); - byte[] referenceManifestDigest = compressedIdentityLinkType.getReferenceManifestDigest(); - byte[] manifestReferenceDigest = compressedIdentityLinkType.getManifestReferenceDigest(); - - IdentityLink idLink = new IdentityLink(issuerTemplate, assertionID, issueInstant, personData, citizenPublicKeys, signatureValue); - idLink.setReferenceDigest(referenceDigest); - idLink.setReferenceManifestDigest(referenceManifestDigest); - idLink.setManifestReferenceDigest(manifestReferenceDigest); - - return idLink; - - } - - /** - * Creates a new CompressedIdentityLink element from the given - * ASN.1 representation of an idLink. - * - * @param idLink - * the ASN.1 representation of an IdentityLink - * @param certificates - * a list of {@link X509Certificate}s containing the corresponding - * public keys - * @param domainId TODO - * @return a new CompressedIdentityLink element - * - * @throws NullPointerException - * if idLink or certificates is - * null - * @throws IllegalArgumentException - * if idLink references certificates not in the range - * of the certificates list - */ - public JAXBElement createCompressedIdentityLink( - at.gv.egiz.idlink.ans1.IdentityLink idLink, - List certificates, String domainId) { - - at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory prFactory = - new at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory(); - - at.buergerkarte.namespaces.personenbindung._20020506_.ObjectFactory pbFactory = - new at.buergerkarte.namespaces.personenbindung._20020506_.ObjectFactory(); - - org.w3._2000._09.xmldsig_.ObjectFactory dsFactory = new org.w3._2000._09.xmldsig_.ObjectFactory(); - - // PersonData - PhysicalPersonData __physicalPersonData = idLink.getPersonData() - .getPhysicalPerson(); - - Value identificationTypeValue = prFactory.createIdentificationTypeValue(); - identificationTypeValue.setValue(__physicalPersonData.getBaseId()); - IdentificationType identificationType = prFactory - .createIdentificationType(); - identificationType.setValue(identificationTypeValue); - if (domainId != null) { - identificationType.setType(domainId); - } else { - identificationType.setType("urn:publicid:gv.at:baseid"); - } - - PersonNameType personNameType = prFactory.createPersonNameType(); - FamilyName personNameTypeFamilyName = prFactory - .createPersonNameTypeFamilyName(); - personNameTypeFamilyName.setValue(__physicalPersonData.getFamilyName()); - personNameType.getFamilyName().add(personNameTypeFamilyName); - personNameType.getGivenName().add(__physicalPersonData.getGivenName()); - - PhysicalPersonType physicalPersonType = prFactory - .createPhysicalPersonType(); - physicalPersonType.getIdentification().add(identificationType); - physicalPersonType.setName(personNameType); - physicalPersonType.setDateOfBirth(__physicalPersonData.getDateOfBirth()); - - // CompressedIdentityLink - CompressedIdentityLinkType compressedIdentityLinkType = pbFactory - .createCompressedIdentityLinkType(); - compressedIdentityLinkType.setIssuerTemplate(idLink.getIssuerTemplate()); - compressedIdentityLinkType.setAssertionID(idLink.getAssertionID()); - compressedIdentityLinkType.setIssueInstant(idLink.getIssueInstant()); - compressedIdentityLinkType.setPersonData(physicalPersonType); - - // CitizenPublicKey - CitizenPublicKey[] __citizenPublicKeys = idLink.getCitizenPublicKeys(); - for (CitizenPublicKey __citizenPublicKey : __citizenPublicKeys) { - - X509Certificate certificate = certificates.get(__citizenPublicKey.getOnToken()); - PublicKey publicKey = certificate.getPublicKey(); - - JAXBElement keyValue; - try { - keyValue = keyValueFactory.createKeyValue(publicKey); - } catch (KeyTypeNotSupportedException e) { - // TODO: handle exception properly - throw new RuntimeException(e); - } - - KeyValueType keyValueType = dsFactory.createKeyValueType(); - keyValueType.getContent().add(keyValue); - - compressedIdentityLinkType.getCitizenPublicKey().add(keyValueType); - } - - compressedIdentityLinkType.setSignatureValue(idLink.getSignatureValue()); - compressedIdentityLinkType.setReferenceDigest(idLink.getReferenceDigest()); - compressedIdentityLinkType.setReferenceManifestDigest(idLink - .getReferenceManifestDigest()); - compressedIdentityLinkType.setManifestReferenceDigest(idLink - .getManifestReferenceDigest()); - JAXBElement compressedIdentityLink = pbFactory - .createCompressedIdentityLink(compressedIdentityLinkType); - - return compressedIdentityLink; - - } - - /** - * Marshall the given compressedIdentityLink into a DOM document - * with the given Nodes as parent and nextSibling - * nodes. - * - * @param compressedIdentityLink - * the CompressedIdentityLink element - * @param parent - * the parent node - * @param nextSibling - * the next sibling node (may be null) - * @param applyWorkarounds - * apply workarounds as spefiyed by - * {@link #applyWorkarounds(Element, int)} - * - * @throws JAXBException - * if an unexpected error occurs while marshalling - * @throws NullPointerException - * if compressdIdentityLink or parent is - * null - */ - public void marshallCompressedIdentityLink( - JAXBElement compressedIdentityLink, - Node parent, Node nextSibling, boolean applyWorkarounds) throws JAXBException { - - DOMResult result = new DOMResult(parent, nextSibling); - - - try { - Marshaller marshaller = jaxbContext.createMarshaller(); - - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - marshaller.marshal(compressedIdentityLink, result); - } catch (PropertyException e) { - throw new RuntimeException(e); - } - - if (applyWorkarounds) { - Element element = (Element) ((nextSibling != null) - ? nextSibling.getPreviousSibling() - : parent.getFirstChild()); - applyWorkarounds(element, 76); - } - - } - - @SuppressWarnings("unchecked") - public CompressedIdentityLinkType unmarshallCompressedIdentityLink(Source source) throws JAXBException { - - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - - return ((JAXBElement) unmarshaller.unmarshal(source)).getValue(); - - } - - /** - * Apply some workarounds to the given CompressedIdentityLink - * element to achieve compatibility with IdentityLink - * transformation stylesheets that have been designed for a (buggy) form of - * the CompressedIdentityLink as produced by a well-known citizen card - * environment implementation. - * - *
    - *
  1. Replace the attribute node URN of the - * NamedCurve element of an ECDSAKeyValue element by - * a child text-node with the same content.
  2. - *
  3. Replace the attribute nodes Value of the X - * and Y elements of an ECDSAKeyValue element by a - * child text-node with the same content.
  4. - *
  5. Insert "\n" at base64LineLength into the Base64 - * content of the Modulus element of an RSAKeyValue - * element. - *
- * - * @param element - * the CompressedIdentityLink element - * @param base64LineLength - * the line length of Base64 content - */ - public void applyWorkarounds(Element element, int base64LineLength) { - - Document document = element.getOwnerDocument(); - - NodeList nodeList = element.getElementsByTagNameNS( - "http://www.w3.org/2001/04/xmldsig-more#", "NamedCurve"); - for (int i = 0; i < nodeList.getLength(); i++) { - Node ecdsaNameCurve = nodeList.item(i); - Attr attrNode = ((Element) ecdsaNameCurve).getAttributeNodeNS(null, - "URN"); - ecdsaNameCurve - .appendChild(document.createTextNode(attrNode.getValue())); - ((Element) ecdsaNameCurve).removeAttributeNode(attrNode); - } - nodeList = document.getElementsByTagNameNS( - "http://www.w3.org/2001/04/xmldsig-more#", "X"); - for (int i = 0; i < nodeList.getLength(); i++) { - Node x = nodeList.item(i); - Attr attrNode = ((Element) x).getAttributeNodeNS(null, "Value"); - x.appendChild(document.createTextNode(attrNode.getValue())); - ((Element) x).removeAttributeNode(attrNode); - } - nodeList = document.getElementsByTagNameNS( - "http://www.w3.org/2001/04/xmldsig-more#", "Y"); - for (int i = 0; i < nodeList.getLength(); i++) { - Node y = nodeList.item(i); - Attr attrNode = ((Element) y).getAttributeNodeNS(null, "Value"); - y.appendChild(document.createTextNode(attrNode.getValue())); - ((Element) y).removeAttributeNode(attrNode); - } - - if (base64LineLength > 0) { - nodeList = document.getElementsByTagNameNS( - "http://www.w3.org/2000/09/xmldsig#", "Modulus"); - for (int i = 0; i < nodeList.getLength(); i++) { - Node modulus = nodeList.item(i); - String value = ((Element) modulus).getTextContent(); - BufferedReader reader = new BufferedReader(new InputStreamReader( - new ByteArrayInputStream(value.getBytes()))); - char[] buff = new char[base64LineLength]; - StringBuffer newValue = new StringBuffer(); - int found = 0; - try { - while ((found = reader.read(buff)) > 0) { - newValue.append(buff, 0, found); - if (found == base64LineLength) - newValue.append('\n'); - } - } catch (IOException e) { - // this should never happen, as we are reading from a ByteArrayInputStream - throw new RuntimeException(e); - } - ((Element) modulus).setTextContent(newValue.toString()); - } - - } - - - } - -} +package at.gv.egiz.idlink; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.security.PublicKey; +import java.security.cert.X509Certificate; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.PropertyException; +import javax.xml.bind.Unmarshaller; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMResult; + +import org.w3._2000._09.xmldsig_.KeyValueType; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import at.buergerkarte.namespaces.personenbindung._20020506_.CompressedIdentityLinkType; +import at.gv.e_government.reference.namespace.persondata._20020228_.AbstractPersonType; +import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType; +import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType; +import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType; +import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value; +import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType.FamilyName; +import at.gv.egiz.idlink.ans1.CitizenPublicKey; +import at.gv.egiz.idlink.ans1.IdentityLink; +import at.gv.egiz.idlink.ans1.PersonData; +import at.gv.egiz.idlink.ans1.PhysicalPersonData; +import at.gv.egiz.marshal.MarshallerFactory; +import at.gv.egiz.marshal.NamespacePrefixMapperImpl; +import at.gv.egiz.xmldsig.KeyTypeNotSupportedException; +import at.gv.egiz.xmldsig.KeyValueFactory; + +public class CompressedIdentityLinkFactory { + + /** + * The instance returned by {@link #getInstance()}. + */ + private static CompressedIdentityLinkFactory instance; + + /** + * The JAXBContext. + */ + private static JAXBContext jaxbContext; + + /** + * The KeyValueFactory. + */ + private static KeyValueFactory keyValueFactory; + + /** + * Get an instance of this CompressedIdentityLinkFactory. + * + * @return an instance of this CompressedIdentityLinkFactory + */ + public synchronized static CompressedIdentityLinkFactory getInstance() { + if (instance == null) { + instance = new CompressedIdentityLinkFactory(); + } + return instance; + } + + /** + * Private constructor. + */ + private CompressedIdentityLinkFactory() { + + keyValueFactory = new KeyValueFactory(); + + StringBuffer packageNames = new StringBuffer(); + packageNames.append(at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(org.w3._2001._04.xmldsig_more_.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(at.buergerkarte.namespaces.personenbindung._20020506_.ObjectFactory.class.getPackage().getName()); + + try { + jaxbContext = JAXBContext.newInstance(packageNames.toString()); + } catch (JAXBException e) { + // we should not get an JAXBException initializing the JAXBContext + throw new RuntimeException(e); + } + + } + + public IdentityLink createIdLink(CompressedIdentityLinkType compressedIdentityLinkType) { + + // IssuerTemplate + String issuerTemplate = compressedIdentityLinkType.getIssuerTemplate(); + + // AssertionId + String assertionID = compressedIdentityLinkType.getAssertionID(); + + // IssueInstant + String issueInstant = compressedIdentityLinkType.getIssueInstant(); + + AbstractPersonType personDataType = compressedIdentityLinkType.getPersonData(); + + String baseId = null; + + List identifications = personDataType.getIdentification(); + for (IdentificationType identificationType : identifications) { + String type = identificationType.getType(); + if ("urn:publicid:gv.at:baseid".equals(type)) { + baseId = identificationType.getValue().getValue(); + } + } + + String givenName = null; + String familyName = null; + String dateOfBirth = null; + + if (personDataType instanceof PhysicalPersonType) { + PhysicalPersonType physicalPersonType = (PhysicalPersonType) personDataType; + PersonNameType name = physicalPersonType.getName(); + List givenNames = name.getGivenName(); + if (!givenNames.isEmpty()) { + givenName = givenNames.get(0); + } + List familyNames = name.getFamilyName(); + if (!familyNames.isEmpty()) { + familyName = familyNames.get(0).getValue(); + } + dateOfBirth = physicalPersonType.getDateOfBirth(); + } + + PhysicalPersonData physicalPersonData = new PhysicalPersonData(baseId, givenName, familyName, dateOfBirth); + PersonData personData = new PersonData(physicalPersonData); + + int numKeys = compressedIdentityLinkType.getCitizenPublicKey().size(); + CitizenPublicKey[] citizenPublicKeys = new CitizenPublicKey[numKeys]; + for (int i = 0; i < numKeys;) { + citizenPublicKeys[i] = new CitizenPublicKey(++i); + } + + byte[] signatureValue = compressedIdentityLinkType.getSignatureValue(); + byte[] referenceDigest = compressedIdentityLinkType.getReferenceDigest(); + byte[] referenceManifestDigest = compressedIdentityLinkType.getReferenceManifestDigest(); + byte[] manifestReferenceDigest = compressedIdentityLinkType.getManifestReferenceDigest(); + + IdentityLink idLink = new IdentityLink(issuerTemplate, assertionID, issueInstant, personData, citizenPublicKeys, signatureValue); + idLink.setReferenceDigest(referenceDigest); + idLink.setReferenceManifestDigest(referenceManifestDigest); + idLink.setManifestReferenceDigest(manifestReferenceDigest); + + return idLink; + + } + + /** + * Creates a new CompressedIdentityLink element from the given + * ASN.1 representation of an idLink. + * + * @param idLink + * the ASN.1 representation of an IdentityLink + * @param certificates + * a list of {@link X509Certificate}s containing the corresponding + * public keys + * @param domainId TODO + * @return a new CompressedIdentityLink element + * + * @throws NullPointerException + * if idLink or certificates is + * null + * @throws IllegalArgumentException + * if idLink references certificates not in the range + * of the certificates list + */ + public JAXBElement createCompressedIdentityLink( + at.gv.egiz.idlink.ans1.IdentityLink idLink, + List certificates, String domainId) { + + at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory prFactory = + new at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory(); + + at.buergerkarte.namespaces.personenbindung._20020506_.ObjectFactory pbFactory = + new at.buergerkarte.namespaces.personenbindung._20020506_.ObjectFactory(); + + org.w3._2000._09.xmldsig_.ObjectFactory dsFactory = new org.w3._2000._09.xmldsig_.ObjectFactory(); + + // PersonData + PhysicalPersonData __physicalPersonData = idLink.getPersonData() + .getPhysicalPerson(); + + Value identificationTypeValue = prFactory.createIdentificationTypeValue(); + identificationTypeValue.setValue(__physicalPersonData.getBaseId()); + IdentificationType identificationType = prFactory + .createIdentificationType(); + identificationType.setValue(identificationTypeValue); + if (domainId != null) { + identificationType.setType(domainId); + } else { + identificationType.setType("urn:publicid:gv.at:baseid"); + } + + PersonNameType personNameType = prFactory.createPersonNameType(); + FamilyName personNameTypeFamilyName = prFactory + .createPersonNameTypeFamilyName(); + personNameTypeFamilyName.setValue(__physicalPersonData.getFamilyName()); + personNameType.getFamilyName().add(personNameTypeFamilyName); + personNameType.getGivenName().add(__physicalPersonData.getGivenName()); + + PhysicalPersonType physicalPersonType = prFactory + .createPhysicalPersonType(); + physicalPersonType.getIdentification().add(identificationType); + physicalPersonType.setName(personNameType); + physicalPersonType.setDateOfBirth(__physicalPersonData.getDateOfBirth()); + + // CompressedIdentityLink + CompressedIdentityLinkType compressedIdentityLinkType = pbFactory + .createCompressedIdentityLinkType(); + compressedIdentityLinkType.setIssuerTemplate(idLink.getIssuerTemplate()); + compressedIdentityLinkType.setAssertionID(idLink.getAssertionID()); + compressedIdentityLinkType.setIssueInstant(idLink.getIssueInstant()); + compressedIdentityLinkType.setPersonData(physicalPersonType); + + // CitizenPublicKey + CitizenPublicKey[] __citizenPublicKeys = idLink.getCitizenPublicKeys(); + for (CitizenPublicKey __citizenPublicKey : __citizenPublicKeys) { + + X509Certificate certificate = certificates.get(__citizenPublicKey.getOnToken()); + PublicKey publicKey = certificate.getPublicKey(); + + JAXBElement keyValue; + try { + keyValue = keyValueFactory.createKeyValue(publicKey); + } catch (KeyTypeNotSupportedException e) { + // TODO: handle exception properly + throw new RuntimeException(e); + } + + KeyValueType keyValueType = dsFactory.createKeyValueType(); + keyValueType.getContent().add(keyValue); + + compressedIdentityLinkType.getCitizenPublicKey().add(keyValueType); + } + + compressedIdentityLinkType.setSignatureValue(idLink.getSignatureValue()); + compressedIdentityLinkType.setReferenceDigest(idLink.getReferenceDigest()); + compressedIdentityLinkType.setReferenceManifestDigest(idLink + .getReferenceManifestDigest()); + compressedIdentityLinkType.setManifestReferenceDigest(idLink + .getManifestReferenceDigest()); + JAXBElement compressedIdentityLink = pbFactory + .createCompressedIdentityLink(compressedIdentityLinkType); + + return compressedIdentityLink; + + } + + /** + * Marshall the given compressedIdentityLink into a DOM document + * with the given Nodes as parent and nextSibling + * nodes. + * + * @param compressedIdentityLink + * the CompressedIdentityLink element + * @param parent + * the parent node + * @param nextSibling + * the next sibling node (may be null) + * @param applyWorkarounds + * apply workarounds as spefiyed by + * {@link #applyWorkarounds(Element, int)} + * + * @throws JAXBException + * if an unexpected error occurs while marshalling + * @throws NullPointerException + * if compressdIdentityLink or parent is + * null + */ + public void marshallCompressedIdentityLink( + JAXBElement compressedIdentityLink, + Node parent, Node nextSibling, boolean applyWorkarounds) throws JAXBException { + + DOMResult result = new DOMResult(parent, nextSibling); + + + try { + Marshaller marshaller = MarshallerFactory.createMarshaller(jaxbContext); + + marshaller.marshal(compressedIdentityLink, result); + } catch (PropertyException e) { + throw new RuntimeException(e); + } + + if (applyWorkarounds) { + Element element = (Element) ((nextSibling != null) + ? nextSibling.getPreviousSibling() + : parent.getFirstChild()); + applyWorkarounds(element, 76); + } + + } + + @SuppressWarnings("unchecked") + public CompressedIdentityLinkType unmarshallCompressedIdentityLink(Source source) throws JAXBException { + + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + + return ((JAXBElement) unmarshaller.unmarshal(source)).getValue(); + + } + + /** + * Apply some workarounds to the given CompressedIdentityLink + * element to achieve compatibility with IdentityLink + * transformation stylesheets that have been designed for a (buggy) form of + * the CompressedIdentityLink as produced by a well-known citizen card + * environment implementation. + * + *
    + *
  1. Replace the attribute node URN of the + * NamedCurve element of an ECDSAKeyValue element by + * a child text-node with the same content.
  2. + *
  3. Replace the attribute nodes Value of the X + * and Y elements of an ECDSAKeyValue element by a + * child text-node with the same content.
  4. + *
  5. Insert "\n" at base64LineLength into the Base64 + * content of the Modulus element of an RSAKeyValue + * element. + *
+ * + * @param element + * the CompressedIdentityLink element + * @param base64LineLength + * the line length of Base64 content + */ + public void applyWorkarounds(Element element, int base64LineLength) { + + Document document = element.getOwnerDocument(); + + NodeList nodeList = element.getElementsByTagNameNS( + "http://www.w3.org/2001/04/xmldsig-more#", "NamedCurve"); + for (int i = 0; i < nodeList.getLength(); i++) { + Node ecdsaNameCurve = nodeList.item(i); + Attr attrNode = ((Element) ecdsaNameCurve).getAttributeNodeNS(null, + "URN"); + ecdsaNameCurve + .appendChild(document.createTextNode(attrNode.getValue())); + ((Element) ecdsaNameCurve).removeAttributeNode(attrNode); + } + nodeList = document.getElementsByTagNameNS( + "http://www.w3.org/2001/04/xmldsig-more#", "X"); + for (int i = 0; i < nodeList.getLength(); i++) { + Node x = nodeList.item(i); + Attr attrNode = ((Element) x).getAttributeNodeNS(null, "Value"); + x.appendChild(document.createTextNode(attrNode.getValue())); + ((Element) x).removeAttributeNode(attrNode); + } + nodeList = document.getElementsByTagNameNS( + "http://www.w3.org/2001/04/xmldsig-more#", "Y"); + for (int i = 0; i < nodeList.getLength(); i++) { + Node y = nodeList.item(i); + Attr attrNode = ((Element) y).getAttributeNodeNS(null, "Value"); + y.appendChild(document.createTextNode(attrNode.getValue())); + ((Element) y).removeAttributeNode(attrNode); + } + + if (base64LineLength > 0) { + nodeList = document.getElementsByTagNameNS( + "http://www.w3.org/2000/09/xmldsig#", "Modulus"); + for (int i = 0; i < nodeList.getLength(); i++) { + Node modulus = nodeList.item(i); + String value = ((Element) modulus).getTextContent(); + BufferedReader reader = new BufferedReader(new InputStreamReader( + new ByteArrayInputStream(value.getBytes()))); + char[] buff = new char[base64LineLength]; + StringBuffer newValue = new StringBuffer(); + int found = 0; + try { + while ((found = reader.read(buff)) > 0) { + newValue.append(buff, 0, found); + if (found == base64LineLength) + newValue.append('\n'); + } + } catch (IOException e) { + // this should never happen, as we are reading from a ByteArrayInputStream + throw new RuntimeException(e); + } + ((Element) modulus).setTextContent(newValue.toString()); + } + + } + + + } + +} diff --git a/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java b/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java index fb7943dc..38597446 100644 --- a/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java +++ b/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java @@ -87,6 +87,8 @@ import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameTy import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType; import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value; import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType.FamilyName; +import at.gv.egiz.marshal.MarshallerFactory; +import at.gv.egiz.marshal.NamespacePrefixMapperImpl; import at.gv.egiz.xmldsig.KeyTypeNotSupportedException; import at.gv.egiz.xmldsig.KeyValueFactory; import oasis.names.tc.saml._1_0.assertion.AnyType; @@ -276,9 +278,7 @@ public class IdentityLinkFactory { DOMResult result = new DOMResult(parent, nextSibling); try { - Marshaller marshaller = jaxbContext.createMarshaller(); - - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + Marshaller marshaller = MarshallerFactory.createMarshaller(jaxbContext, true); marshaller.marshal(identityLink, result); } catch (PropertyException e) { diff --git a/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java b/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java new file mode 100644 index 00000000..ccebcc81 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java @@ -0,0 +1,52 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed 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 at.gv.egiz.marshal; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.PropertyException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author Clemens Orthacker + */ +public class MarshallerFactory { + + private static final Log log = LogFactory.getLog(MarshallerFactory.class); + + public static Marshaller createMarshaller(JAXBContext ctx, boolean formattedOutput) throws JAXBException { + Marshaller m = ctx.createMarshaller(); + try { + if (formattedOutput) { + log.trace("setting marshaller property FORMATTED_OUTPUT"); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + } + log.trace("setting marshaller property NamespacePrefixMapper"); + m.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapperImpl()); + } catch (PropertyException ex) { + log.info("failed to set marshaller property: " + ex.getMessage()); + } + return m; + } + + public static Marshaller createMarshaller(JAXBContext ctx) throws JAXBException { + return createMarshaller(ctx, false); + } +} diff --git a/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java b/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java new file mode 100644 index 00000000..a08c1188 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java @@ -0,0 +1,86 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed 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 at.gv.egiz.marshal; + +//import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper; +import com.sun.xml.bind.marshaller.NamespacePrefixMapper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author Clemens Orthacker + */ +public class NamespacePrefixMapperImpl extends NamespacePrefixMapper { + + private static final Log log = LogFactory.getLog(NamespacePrefixMapperImpl.class); + + @Override + public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { + + if (log.isTraceEnabled()) { + log.trace("prefix for namespace " + namespaceUri + " requested"); + } + if ("http://www.w3.org/2001/XMLSchema-instance".equals(namespaceUri)) { + return "xsi"; + } + + if ("http://www.w3.org/2000/09/xmldsig#".equals(namespaceUri)) { + return "dsig"; + } + + if ("http://www.buergerkarte.at/namespaces/securitylayer/1.2#".equals(namespaceUri)) { + return "sl"; + } + + if ("http://www.buergerkarte.at/cardchannel".equals(namespaceUri)) { + return "cc"; + } + + if ("http://www.w3.org/2001/04/xmldsig-more#".equals(namespaceUri)) { + return "ecdsa"; + } + + if ("http://reference.e-government.gv.at/namespace/persondata/20020228#".equals(namespaceUri)) { + return "pr"; + } + + if ("urn:oasis:names:tc:SAML:1.0:assertion".equals(namespaceUri)) { + return "saml"; + } + + if ("http://uri.etsi.org/01903/v1.1.1#".equals(namespaceUri)) { + return "xades"; + } + + return suggestion; + } + + /** + * Returns a list of namespace URIs that should be declared + * at the root element. + *

+ * By default, the JAXB RI produces namespace declarations only when + * they are necessary, only at where they are used. Because of this + * lack of look-ahead, sometimes the marshaller produces a lot of + * namespace declarations that look redundant to human eyes. For example, + */ + @Override + public String[] getPreDeclaredNamespaceUris() { + return new String[]{ "http://www.buergerkarte.at/namespaces/securitylayer/1.2#" }; + } +} diff --git a/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java b/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java index ae159215..71ca1db9 100644 --- a/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java +++ b/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java @@ -14,212 +14,212 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package at.gv.egiz.xades; - -import java.math.BigInteger; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509Certificate; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.List; -import java.util.TimeZone; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.PropertyException; -import javax.xml.crypto.dsig.DigestMethod; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; - -import org.etsi.uri._01903.v1_1.CertIDListType; -import org.etsi.uri._01903.v1_1.CertIDType; -import org.etsi.uri._01903.v1_1.DataObjectFormatType; -import org.etsi.uri._01903.v1_1.DigestAlgAndValueType; -import org.etsi.uri._01903.v1_1.QualifyingPropertiesType; -import org.etsi.uri._01903.v1_1.SignaturePolicyIdentifierType; -import org.etsi.uri._01903.v1_1.SignedDataObjectPropertiesType; -import org.etsi.uri._01903.v1_1.SignedPropertiesType; -import org.etsi.uri._01903.v1_1.SignedSignaturePropertiesType; -import org.w3._2000._09.xmldsig_.DigestMethodType; -import org.w3._2000._09.xmldsig_.X509IssuerSerialType; -import org.w3c.dom.Node; - -public class QualifyingPropertiesFactory { - - public static String NS_URI_V1_1_1 = "http://uri.etsi.org/01903/v1.1.1#"; - - public static String SIGNED_PROPERTIES_REFERENCE_TYPE_V1_1_1 = NS_URI_V1_1_1 + "SignedProperties"; - - private static QualifyingPropertiesFactory instance; - - /** - * The JAXBContext. - */ - private static JAXBContext jaxbContext; - - public static synchronized QualifyingPropertiesFactory getInstance() { - if (instance == null) { - instance = new QualifyingPropertiesFactory(); - } - return instance; - } - - private DatatypeFactory datatypeFactory; - - private org.etsi.uri._01903.v1_1.ObjectFactory qpFactory; - - private org.w3._2000._09.xmldsig_.ObjectFactory dsFactory; - - public QualifyingPropertiesFactory() { - - try { - datatypeFactory = DatatypeFactory.newInstance(); - } catch (DatatypeConfigurationException e) { - throw new RuntimeException(e); - } - - qpFactory = new org.etsi.uri._01903.v1_1.ObjectFactory(); - - dsFactory = new org.w3._2000._09.xmldsig_.ObjectFactory(); - - StringBuffer packageNames = new StringBuffer(); - - packageNames.append(org.etsi.uri._01903.v1_1.ObjectFactory.class.getPackage().getName()); - packageNames.append(":"); - packageNames.append(org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName()); - - try { - jaxbContext = JAXBContext.newInstance(packageNames.toString()); - } catch (JAXBException e) { - // we should not get an JAXBException initializing the JAXBContext - throw new RuntimeException(e); - } - - } - - public DigestAlgAndValueType createDigestAlgAndValueType(X509Certificate certificate) throws QualifyingPropertiesException { - - DigestMethodType digestMethodType = dsFactory.createDigestMethodType(); - digestMethodType.setAlgorithm(DigestMethod.SHA1); - - byte[] digest; - try { - MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); - digest = messageDigest.digest(certificate.getEncoded()); - } catch (CertificateEncodingException e) { - throw new QualifyingPropertiesException(e); - } catch (NoSuchAlgorithmException e) { - throw new QualifyingPropertiesException(e); - } - - DigestAlgAndValueType digestAlgAndValueType = qpFactory.createDigestAlgAndValueType(); - digestAlgAndValueType.setDigestMethod(digestMethodType); - digestAlgAndValueType.setDigestValue(digest); - - return digestAlgAndValueType; - - } - - public X509IssuerSerialType createX509IssuerSerialType(X509Certificate certificate) { - - String name = certificate.getIssuerX500Principal().getName("RFC2253"); - BigInteger serialNumber = certificate.getSerialNumber(); - - X509IssuerSerialType issuerSerialType = dsFactory.createX509IssuerSerialType(); - issuerSerialType.setX509IssuerName(name); - issuerSerialType.setX509SerialNumber(serialNumber); - - return issuerSerialType; - - } - - public DataObjectFormatType createDataObjectFormatType(String objectReference, String mimeType, String description) { - - DataObjectFormatType dataObjectFormatType = qpFactory.createDataObjectFormatType(); - dataObjectFormatType.setObjectReference(objectReference); - - if (mimeType != null) { - dataObjectFormatType.setMimeType(mimeType); - } - if (description != null) { - dataObjectFormatType.setDescription(description); - } - - return dataObjectFormatType; - } - - public JAXBElement createQualifyingProperties111(Date signingTime, List certificates, String idValue, List dataObjectFormats) throws QualifyingPropertiesException { - - GregorianCalendar gregorianCalendar = new GregorianCalendar(); - gregorianCalendar.setTimeZone(TimeZone.getTimeZone("UTC")); - gregorianCalendar.setTime(signingTime); - - SignedSignaturePropertiesType signedSignaturePropertiesType = qpFactory.createSignedSignaturePropertiesType(); - - // SigningTime - XMLGregorianCalendar xmlGregorianCalendar = datatypeFactory.newXMLGregorianCalendar(gregorianCalendar); - xmlGregorianCalendar.setFractionalSecond(null); - signedSignaturePropertiesType.setSigningTime(xmlGregorianCalendar); - - // SigningCertificate - CertIDListType certIDListType = qpFactory.createCertIDListType(); - List certIDs = certIDListType.getCert(); - - for (X509Certificate certificate : certificates) { - - CertIDType certIDType = qpFactory.createCertIDType(); - certIDType.setCertDigest(createDigestAlgAndValueType(certificate)); - certIDType.setIssuerSerial(createX509IssuerSerialType(certificate)); - - certIDs.add(certIDType); - - } - signedSignaturePropertiesType.setSigningCertificate(certIDListType); - - // SignaturePolicy - SignaturePolicyIdentifierType signaturePolicyIdentifierType = qpFactory.createSignaturePolicyIdentifierType(); - signaturePolicyIdentifierType.setSignaturePolicyImplied(new SignaturePolicyIdentifierType.SignaturePolicyImplied()); - signedSignaturePropertiesType.setSignaturePolicyIdentifier(signaturePolicyIdentifierType); - - // SignedProperties - SignedPropertiesType signedPropertiesType = qpFactory.createSignedPropertiesType(); - signedPropertiesType.setSignedSignatureProperties(signedSignaturePropertiesType); - - // DataObjectFormat - if (dataObjectFormats != null && !dataObjectFormats.isEmpty()) { - SignedDataObjectPropertiesType signedDataObjectPropertiesType = qpFactory.createSignedDataObjectPropertiesType(); - List dataObjectFormatTypes = signedDataObjectPropertiesType.getDataObjectFormat(); - dataObjectFormatTypes.addAll(dataObjectFormats); - signedPropertiesType.setSignedDataObjectProperties(signedDataObjectPropertiesType); - } - - signedPropertiesType.setId(idValue); - - // QualifyingProperties - QualifyingPropertiesType qualifyingPropertiesType = qpFactory.createQualifyingPropertiesType(); - qualifyingPropertiesType.setSignedProperties(signedPropertiesType); - - return qpFactory.createQualifyingProperties(qualifyingPropertiesType); - - } - - public void marshallQualifyingProperties(JAXBElement qualifyingProperties, Node parent) throws JAXBException { - - try { - Marshaller marshaller = jaxbContext.createMarshaller(); - - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - marshaller.marshal(qualifyingProperties, parent); - } catch (PropertyException e) { - throw new RuntimeException(e); - } - - } - -} +package at.gv.egiz.xades; + +import at.gv.egiz.marshal.MarshallerFactory; +import at.gv.egiz.marshal.NamespacePrefixMapperImpl; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.TimeZone; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.PropertyException; +import javax.xml.crypto.dsig.DigestMethod; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.etsi.uri._01903.v1_1.CertIDListType; +import org.etsi.uri._01903.v1_1.CertIDType; +import org.etsi.uri._01903.v1_1.DataObjectFormatType; +import org.etsi.uri._01903.v1_1.DigestAlgAndValueType; +import org.etsi.uri._01903.v1_1.QualifyingPropertiesType; +import org.etsi.uri._01903.v1_1.SignaturePolicyIdentifierType; +import org.etsi.uri._01903.v1_1.SignedDataObjectPropertiesType; +import org.etsi.uri._01903.v1_1.SignedPropertiesType; +import org.etsi.uri._01903.v1_1.SignedSignaturePropertiesType; +import org.w3._2000._09.xmldsig_.DigestMethodType; +import org.w3._2000._09.xmldsig_.X509IssuerSerialType; +import org.w3c.dom.Node; + +public class QualifyingPropertiesFactory { + + public static String NS_URI_V1_1_1 = "http://uri.etsi.org/01903/v1.1.1#"; + + public static String SIGNED_PROPERTIES_REFERENCE_TYPE_V1_1_1 = NS_URI_V1_1_1 + "SignedProperties"; + + private static QualifyingPropertiesFactory instance; + + /** + * The JAXBContext. + */ + private static JAXBContext jaxbContext; + + public static synchronized QualifyingPropertiesFactory getInstance() { + if (instance == null) { + instance = new QualifyingPropertiesFactory(); + } + return instance; + } + + private DatatypeFactory datatypeFactory; + + private org.etsi.uri._01903.v1_1.ObjectFactory qpFactory; + + private org.w3._2000._09.xmldsig_.ObjectFactory dsFactory; + + public QualifyingPropertiesFactory() { + + try { + datatypeFactory = DatatypeFactory.newInstance(); + } catch (DatatypeConfigurationException e) { + throw new RuntimeException(e); + } + + qpFactory = new org.etsi.uri._01903.v1_1.ObjectFactory(); + + dsFactory = new org.w3._2000._09.xmldsig_.ObjectFactory(); + + StringBuffer packageNames = new StringBuffer(); + + packageNames.append(org.etsi.uri._01903.v1_1.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName()); + + try { + jaxbContext = JAXBContext.newInstance(packageNames.toString()); + } catch (JAXBException e) { + // we should not get an JAXBException initializing the JAXBContext + throw new RuntimeException(e); + } + + } + + public DigestAlgAndValueType createDigestAlgAndValueType(X509Certificate certificate) throws QualifyingPropertiesException { + + DigestMethodType digestMethodType = dsFactory.createDigestMethodType(); + digestMethodType.setAlgorithm(DigestMethod.SHA1); + + byte[] digest; + try { + MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); + digest = messageDigest.digest(certificate.getEncoded()); + } catch (CertificateEncodingException e) { + throw new QualifyingPropertiesException(e); + } catch (NoSuchAlgorithmException e) { + throw new QualifyingPropertiesException(e); + } + + DigestAlgAndValueType digestAlgAndValueType = qpFactory.createDigestAlgAndValueType(); + digestAlgAndValueType.setDigestMethod(digestMethodType); + digestAlgAndValueType.setDigestValue(digest); + + return digestAlgAndValueType; + + } + + public X509IssuerSerialType createX509IssuerSerialType(X509Certificate certificate) { + + String name = certificate.getIssuerX500Principal().getName("RFC2253"); + BigInteger serialNumber = certificate.getSerialNumber(); + + X509IssuerSerialType issuerSerialType = dsFactory.createX509IssuerSerialType(); + issuerSerialType.setX509IssuerName(name); + issuerSerialType.setX509SerialNumber(serialNumber); + + return issuerSerialType; + + } + + public DataObjectFormatType createDataObjectFormatType(String objectReference, String mimeType, String description) { + + DataObjectFormatType dataObjectFormatType = qpFactory.createDataObjectFormatType(); + dataObjectFormatType.setObjectReference(objectReference); + + if (mimeType != null) { + dataObjectFormatType.setMimeType(mimeType); + } + if (description != null) { + dataObjectFormatType.setDescription(description); + } + + return dataObjectFormatType; + } + + public JAXBElement createQualifyingProperties111(Date signingTime, List certificates, String idValue, List dataObjectFormats) throws QualifyingPropertiesException { + + GregorianCalendar gregorianCalendar = new GregorianCalendar(); + gregorianCalendar.setTimeZone(TimeZone.getTimeZone("UTC")); + gregorianCalendar.setTime(signingTime); + + SignedSignaturePropertiesType signedSignaturePropertiesType = qpFactory.createSignedSignaturePropertiesType(); + + // SigningTime + XMLGregorianCalendar xmlGregorianCalendar = datatypeFactory.newXMLGregorianCalendar(gregorianCalendar); + xmlGregorianCalendar.setFractionalSecond(null); + signedSignaturePropertiesType.setSigningTime(xmlGregorianCalendar); + + // SigningCertificate + CertIDListType certIDListType = qpFactory.createCertIDListType(); + List certIDs = certIDListType.getCert(); + + for (X509Certificate certificate : certificates) { + + CertIDType certIDType = qpFactory.createCertIDType(); + certIDType.setCertDigest(createDigestAlgAndValueType(certificate)); + certIDType.setIssuerSerial(createX509IssuerSerialType(certificate)); + + certIDs.add(certIDType); + + } + signedSignaturePropertiesType.setSigningCertificate(certIDListType); + + // SignaturePolicy + SignaturePolicyIdentifierType signaturePolicyIdentifierType = qpFactory.createSignaturePolicyIdentifierType(); + signaturePolicyIdentifierType.setSignaturePolicyImplied(new SignaturePolicyIdentifierType.SignaturePolicyImplied()); + signedSignaturePropertiesType.setSignaturePolicyIdentifier(signaturePolicyIdentifierType); + + // SignedProperties + SignedPropertiesType signedPropertiesType = qpFactory.createSignedPropertiesType(); + signedPropertiesType.setSignedSignatureProperties(signedSignaturePropertiesType); + + // DataObjectFormat + if (dataObjectFormats != null && !dataObjectFormats.isEmpty()) { + SignedDataObjectPropertiesType signedDataObjectPropertiesType = qpFactory.createSignedDataObjectPropertiesType(); + List dataObjectFormatTypes = signedDataObjectPropertiesType.getDataObjectFormat(); + dataObjectFormatTypes.addAll(dataObjectFormats); + signedPropertiesType.setSignedDataObjectProperties(signedDataObjectPropertiesType); + } + + signedPropertiesType.setId(idValue); + + // QualifyingProperties + QualifyingPropertiesType qualifyingPropertiesType = qpFactory.createQualifyingPropertiesType(); + qualifyingPropertiesType.setSignedProperties(signedPropertiesType); + + return qpFactory.createQualifyingProperties(qualifyingPropertiesType); + + } + + public void marshallQualifyingProperties(JAXBElement qualifyingProperties, Node parent) throws JAXBException { + + try { + Marshaller marshaller = MarshallerFactory.createMarshaller(jaxbContext, true); + + marshaller.marshal(qualifyingProperties, parent); + } catch (PropertyException e) { + throw new RuntimeException(e); + } + + } + +} -- cgit v1.2.3