diff options
Diffstat (limited to 'utils/src/main/java/at/gv/egiz/idlink')
-rw-r--r-- | utils/src/main/java/at/gv/egiz/idlink/CompressedIdentityLinkFactory.java | 800 | ||||
-rw-r--r-- | utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java | 6 |
2 files changed, 403 insertions, 403 deletions
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 <code>JAXBContext</code>.
- */
- private static JAXBContext jaxbContext;
-
- /**
- * The <code>KeyValueFactory</code>.
- */
- private static KeyValueFactory keyValueFactory;
-
- /**
- * Get an instance of this <code>CompressedIdentityLinkFactory</code>.
- *
- * @return an instance of this <code>CompressedIdentityLinkFactory</code>
- */
- 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<IdentificationType> 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<String> givenNames = name.getGivenName();
- if (!givenNames.isEmpty()) {
- givenName = givenNames.get(0);
- }
- List<FamilyName> 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 <code>CompressedIdentityLink</code> element from the given
- * ASN.1 representation of an <code>idLink</code>.
- *
- * @param idLink
- * the ASN.1 representation of an <code>IdentityLink</code>
- * @param certificates
- * a list of {@link X509Certificate}s containing the corresponding
- * public keys
- * @param domainId TODO
- * @return a new <code>CompressedIdentityLink</code> element
- *
- * @throws NullPointerException
- * if <code>idLink</code> or <code>certificates</code> is
- * <code>null</code>
- * @throws IllegalArgumentException
- * if <code>idLink</code> references certificates not in the range
- * of the <code>certificates</code> list
- */
- public JAXBElement<CompressedIdentityLinkType> createCompressedIdentityLink(
- at.gv.egiz.idlink.ans1.IdentityLink idLink,
- List<X509Certificate> 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<CompressedIdentityLinkType> compressedIdentityLink = pbFactory
- .createCompressedIdentityLink(compressedIdentityLinkType);
-
- return compressedIdentityLink;
-
- }
-
- /**
- * Marshall the given <code>compressedIdentityLink</code> into a DOM document
- * with the given Nodes as <code>parent</code> and <code>nextSibling</code>
- * nodes.
- *
- * @param compressedIdentityLink
- * the <code>CompressedIdentityLink</code> element
- * @param parent
- * the parent node
- * @param nextSibling
- * the next sibling node (may be <code>null</code>)
- * @param applyWorkarounds
- * apply workarounds as spefiyed by
- * {@link #applyWorkarounds(Element, int)}
- *
- * @throws JAXBException
- * if an unexpected error occurs while marshalling
- * @throws NullPointerException
- * if <code>compressdIdentityLink</code> or <code>parent</code> is
- * <code>null</code>
- */
- public void marshallCompressedIdentityLink(
- JAXBElement<CompressedIdentityLinkType> 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<CompressedIdentityLinkType>) unmarshaller.unmarshal(source)).getValue();
-
- }
-
- /**
- * Apply some workarounds to the given CompressedIdentityLink
- * <code>element</code> 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.
- *
- * <ol>
- * <li>Replace the attribute node <code>URN</code> of the
- * <code>NamedCurve</code> element of an <code>ECDSAKeyValue</code> element by
- * a child text-node with the same content.</li>
- * <li>Replace the attribute nodes <code>Value</code> of the <code>X</code>
- * and <code>Y</code> elements of an <code>ECDSAKeyValue</code> element by a
- * child text-node with the same content.</li>
- * <li>Insert "\n" at <code>base64LineLength</code> into the Base64
- * content of the <code>Modulus</code> element of an <code>RSAKeyValue</code>
- * element.
- * </ol>
- *
- * @param element
- * the <code>CompressedIdentityLink</code> 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 <code>JAXBContext</code>. + */ + private static JAXBContext jaxbContext; + + /** + * The <code>KeyValueFactory</code>. + */ + private static KeyValueFactory keyValueFactory; + + /** + * Get an instance of this <code>CompressedIdentityLinkFactory</code>. + * + * @return an instance of this <code>CompressedIdentityLinkFactory</code> + */ + 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<IdentificationType> 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<String> givenNames = name.getGivenName(); + if (!givenNames.isEmpty()) { + givenName = givenNames.get(0); + } + List<FamilyName> 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 <code>CompressedIdentityLink</code> element from the given + * ASN.1 representation of an <code>idLink</code>. + * + * @param idLink + * the ASN.1 representation of an <code>IdentityLink</code> + * @param certificates + * a list of {@link X509Certificate}s containing the corresponding + * public keys + * @param domainId TODO + * @return a new <code>CompressedIdentityLink</code> element + * + * @throws NullPointerException + * if <code>idLink</code> or <code>certificates</code> is + * <code>null</code> + * @throws IllegalArgumentException + * if <code>idLink</code> references certificates not in the range + * of the <code>certificates</code> list + */ + public JAXBElement<CompressedIdentityLinkType> createCompressedIdentityLink( + at.gv.egiz.idlink.ans1.IdentityLink idLink, + List<X509Certificate> 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<CompressedIdentityLinkType> compressedIdentityLink = pbFactory + .createCompressedIdentityLink(compressedIdentityLinkType); + + return compressedIdentityLink; + + } + + /** + * Marshall the given <code>compressedIdentityLink</code> into a DOM document + * with the given Nodes as <code>parent</code> and <code>nextSibling</code> + * nodes. + * + * @param compressedIdentityLink + * the <code>CompressedIdentityLink</code> element + * @param parent + * the parent node + * @param nextSibling + * the next sibling node (may be <code>null</code>) + * @param applyWorkarounds + * apply workarounds as spefiyed by + * {@link #applyWorkarounds(Element, int)} + * + * @throws JAXBException + * if an unexpected error occurs while marshalling + * @throws NullPointerException + * if <code>compressdIdentityLink</code> or <code>parent</code> is + * <code>null</code> + */ + public void marshallCompressedIdentityLink( + JAXBElement<CompressedIdentityLinkType> 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<CompressedIdentityLinkType>) unmarshaller.unmarshal(source)).getValue(); + + } + + /** + * Apply some workarounds to the given CompressedIdentityLink + * <code>element</code> 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. + * + * <ol> + * <li>Replace the attribute node <code>URN</code> of the + * <code>NamedCurve</code> element of an <code>ECDSAKeyValue</code> element by + * a child text-node with the same content.</li> + * <li>Replace the attribute nodes <code>Value</code> of the <code>X</code> + * and <code>Y</code> elements of an <code>ECDSAKeyValue</code> element by a + * child text-node with the same content.</li> + * <li>Insert "\n" at <code>base64LineLength</code> into the Base64 + * content of the <code>Modulus</code> element of an <code>RSAKeyValue</code> + * element. + * </ol> + * + * @param element + * the <code>CompressedIdentityLink</code> 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) { |