/* * reserved comment block * DO NOT REMOVE OR ALTER! *//* * Copyright 2005 The Apache Software Foundation. * * 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. * *//* * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. *//* * $Id: DOMKeyValue.java,v 1.2 2008/07/24 15:20:32 mullan Exp $ */package org.jcp.xml.dsig.internal.dom; import javax.xml.crypto.*;import javax.xml.crypto.dom.DOMCryptoContext;import javax.xml.crypto.dsig.*;import javax.xml.crypto.dsig.keyinfo.KeyValue; import java.security.KeyException;import java.security.KeyFactory;import java.security.NoSuchAlgorithmException;import java.security.PublicKey;import java.security.interfaces.DSAParams;import java.security.interfaces.DSAPublicKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.DSAPublicKeySpec;import java.security.spec.InvalidKeySpecException;import java.security.spec.KeySpec;import java.security.spec.RSAPublicKeySpec;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node; /** * DOM-based implementation of KeyValue. * * @author Sean Mullan */public final class DOMKeyValue extends DOMStructure implements KeyValue { private KeyFactory rsakf, dsakf; private PublicKey publicKey; private javax.xml.crypto.dom.DOMStructure externalPublicKey; // DSAKeyValue CryptoBinaries private DOMCryptoBinary p, q, g, y, j, seed, pgen; // RSAKeyValue CryptoBinaries private DOMCryptoBinary modulus, exponent; public DOMKeyValue(PublicKey key) throws KeyException { if (key == null) { throw new NullPointerException("key cannot be null"); } this.publicKey = key; if (key instanceof DSAPublicKey) { DSAPublicKey dkey = (DSAPublicKey) key; DSAParams params = dkey.getParams(); p = new DOMCryptoBinary(params.getP()); q = new DOMCryptoBinary(params.getQ()); g = new DOMCryptoBinary(params.getG()); y = new DOMCryptoBinary(dkey.getY()); } else if (key instanceof RSAPublicKey) { RSAPublicKey rkey = (RSAPublicKey) key; exponent = new DOMCryptoBinary(rkey.getPublicExponent()); modulus = new DOMCryptoBinary(rkey.getModulus()); } else { throw new KeyException("unsupported key algorithm: " + key.getAlgorithm()); } } /** * Creates a <code>DOMKeyValue</code> from an element. * * @param kvElem a KeyValue element */ public DOMKeyValue(Element kvElem) throws MarshalException { Element kvtElem = DOMUtils.getFirstChildElement(kvElem); if (kvtElem.getLocalName().equals("DSAKeyValue")) { publicKey = unmarshalDSAKeyValue(kvtElem); } else if (kvtElem.getLocalName().equals("RSAKeyValue")) { publicKey = unmarshalRSAKeyValue(kvtElem); } else { publicKey = null; externalPublicKey = new javax.xml.crypto.dom.DOMStructure(kvtElem); } } public PublicKey getPublicKey() throws KeyException { if (publicKey == null) { throw new KeyException("can't convert KeyValue to PublicKey"); } else { return publicKey; } } public void marshal(Node parent, String dsPrefix, DOMCryptoContext context) throws MarshalException { Document ownerDoc = DOMUtils.getOwnerDocument(parent); // create KeyValue element Element kvElem = DOMUtils.createElement (ownerDoc, "KeyValue", XMLSignature.XMLNS, dsPrefix); marshalPublicKey(kvElem, ownerDoc, dsPrefix, context); parent.appendChild(kvElem); } private void marshalPublicKey(Node parent, Document doc, String dsPrefix, DOMCryptoContext context) throws MarshalException { if (publicKey != null) { if (publicKey instanceof DSAPublicKey) { // create and append DSAKeyValue element marshalDSAPublicKey(parent, doc, dsPrefix, context); } else if (publicKey instanceof RSAPublicKey) { // create and append RSAKeyValue element marshalRSAPublicKey(parent, doc, dsPrefix, context); } else { throw new MarshalException(publicKey.getAlgorithm() + " public key algorithm not supported"); } } else { parent.appendChild(externalPublicKey.getNode()); } } private void marshalDSAPublicKey(Node parent, Document doc, String dsPrefix, DOMCryptoContext context) throws MarshalException { Element dsaElem = DOMUtils.createElement (doc, "DSAKeyValue", XMLSignature.XMLNS, dsPrefix); // parameters J, Seed & PgenCounter are not included Element pElem = DOMUtils.createElement (doc, "P", XMLSignature.XMLNS, dsPrefix); Element qElem = DOMUtils.createElement (doc, "Q", XMLSignature.XMLNS, dsPrefix); Element gElem = DOMUtils.createElement (doc, "G", XMLSignature.XMLNS, dsPrefix); Element yElem = DOMUtils.createElement (doc, "Y", XMLSignature.XMLNS, dsPrefix); p.marshal(pElem, dsPrefix, context); q.marshal(qElem, dsPrefix, context); g.marshal(gElem, dsPrefix, context); y.marshal(yElem, dsPrefix, context); dsaElem.appendChild(pElem); dsaElem.appendChild(qElem); dsaElem.appendChild(gElem); dsaElem.appendChild(yElem); parent.appendChild(dsaElem); } private void marshalRSAPublicKey(Node parent, Document doc, String dsPrefix, DOMCryptoContext context) throws MarshalException { Element rsaElem = DOMUtils.createElement (doc, "RSAKeyValue", XMLSignature.XMLNS, dsPrefix); Element modulusElem = DOMUtils.createElement (doc, "Modulus", XMLSignature.XMLNS, dsPrefix); Element exponentElem = DOMUtils.createElement (doc, "Exponent", XMLSignature.XMLNS, dsPrefix); modulus.marshal(modulusElem, dsPrefix, context); exponent.marshal(exponentElem, dsPrefix, context); rsaElem.appendChild(modulusElem); rsaElem.appendChild(exponentElem); parent.appendChild(rsaElem); } private DSAPublicKey unmarshalDSAKeyValue(Element kvtElem) throws MarshalException { if (dsakf == null) { try { dsakf = KeyFactory.getInstance("DSA"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("unable to create DSA KeyFactory: " + e.getMessage()); } } Element curElem = DOMUtils.getFirstChildElement(kvtElem); // check for P and Q if (curElem.getLocalName().equals("P")) { p = new DOMCryptoBinary(curElem.getFirstChild()); curElem = DOMUtils.getNextSiblingElement(curElem); q = new DOMCryptoBinary(curElem.getFirstChild()); curElem = DOMUtils.getNextSiblingElement(curElem); } if (curElem.getLocalName().equals("G")) { g = new DOMCryptoBinary(curElem.getFirstChild()); curElem = DOMUtils.getNextSiblingElement(curElem); } y = new DOMCryptoBinary(curElem.getFirstChild()); curElem = DOMUtils.getNextSiblingElement(curElem); if (curElem != null && curElem.getLocalName().equals("J")) { j = new DOMCryptoBinary(curElem.getFirstChild()); curElem = DOMUtils.getNextSiblingElement(curElem); } if (curElem != null) { seed = new DOMCryptoBinary(curElem.getFirstChild()); curElem = DOMUtils.getNextSiblingElement(curElem); pgen = new DOMCryptoBinary(curElem.getFirstChild()); } //@@@ do we care about j, pgenCounter or seed? DSAPublicKeySpec spec = new DSAPublicKeySpec (y.getBigNum(), p.getBigNum(), q.getBigNum(), g.getBigNum()); return (DSAPublicKey) generatePublicKey(dsakf, spec); } private RSAPublicKey unmarshalRSAKeyValue(Element kvtElem) throws MarshalException { if (rsakf == null) { try { rsakf = KeyFactory.getInstance("RSA"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("unable to create RSA KeyFactory: " + e.getMessage()); } } Element modulusElem = DOMUtils.getFirstChildElement(kvtElem); modulus = new DOMCryptoBinary(modulusElem.getFirstChild()); Element exponentElem = DOMUtils.getNextSiblingElement(modulusElem); exponent = new DOMCryptoBinary(exponentElem.getFirstChild()); RSAPublicKeySpec spec = new RSAPublicKeySpec (modulus.getBigNum(), exponent.getBigNum()); return (RSAPublicKey) generatePublicKey(rsakf, spec); } private PublicKey generatePublicKey(KeyFactory kf, KeySpec keyspec) { try { return kf.generatePublic(keyspec); } catch (InvalidKeySpecException e) { //@@@ should dump exception to log return null; } } public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof KeyValue)) { return false; } try { KeyValue kv = (KeyValue) obj; if (publicKey == null ) { if (kv.getPublicKey() != null) { return false; } } else if (!publicKey.equals(kv.getPublicKey())) { return false; } } catch (KeyException ke) { // no practical way to determine if the keys are equal return false; } return true; }}
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 2005 The Apache Software Foundation.
*
* 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.
*
*/
/*
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
*/
/*
* $Id: DOMKeyValue.java,v 1.2 2008/07/24 15:20:32 mullan Exp $
*/
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import java.security.KeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.RSAPublicKeySpec;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* DOM-based implementation of KeyValue.
*
* @author Sean Mullan
*/
public final class DOMKeyValue extends DOMStructure implements KeyValue {
private KeyFactory rsakf, dsakf;
private PublicKey publicKey;
private javax.xml.crypto.dom.DOMStructure externalPublicKey;
// DSAKeyValue CryptoBinaries
private DOMCryptoBinary p, q, g, y, j, seed, pgen;
// RSAKeyValue CryptoBinaries
private DOMCryptoBinary modulus, exponent;
public DOMKeyValue(PublicKey key) throws KeyException {
if (key == null) {
throw new NullPointerException("key cannot be null");
}
this.publicKey = key;
if (key instanceof DSAPublicKey) {
DSAPublicKey dkey = (DSAPublicKey) key;
DSAParams params = dkey.getParams();
p = new DOMCryptoBinary(params.getP());
q = new DOMCryptoBinary(params.getQ());
g = new DOMCryptoBinary(params.getG());
y = new DOMCryptoBinary(dkey.getY());
} else if (key instanceof RSAPublicKey) {
RSAPublicKey rkey = (RSAPublicKey) key;
exponent = new DOMCryptoBinary(rkey.getPublicExponent());
modulus = new DOMCryptoBinary(rkey.getModulus());
} else {
throw new KeyException("unsupported key algorithm: " +
key.getAlgorithm());
}
}
/**
* Creates a <code>DOMKeyValue</code> from an element.
*
* @param kvElem a KeyValue element
*/
public DOMKeyValue(Element kvElem) throws MarshalException {
Element kvtElem = DOMUtils.getFirstChildElement(kvElem);
if (kvtElem.getLocalName().equals("DSAKeyValue")) {
publicKey = unmarshalDSAKeyValue(kvtElem);
} else if (kvtElem.getLocalName().equals("RSAKeyValue")) {
publicKey = unmarshalRSAKeyValue(kvtElem);
} else {
publicKey = null;
externalPublicKey = new javax.xml.crypto.dom.DOMStructure(kvtElem);
}
}
public PublicKey getPublicKey() throws KeyException {
if (publicKey == null) {
throw new KeyException("can't convert KeyValue to PublicKey");
} else {
return publicKey;
}
}
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException {
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
// create KeyValue element
Element kvElem = DOMUtils.createElement
(ownerDoc, "KeyValue", XMLSignature.XMLNS, dsPrefix);
marshalPublicKey(kvElem, ownerDoc, dsPrefix, context);
parent.appendChild(kvElem);
}
private void marshalPublicKey(Node parent, Document doc, String dsPrefix,
DOMCryptoContext context) throws MarshalException {
if (publicKey != null) {
if (publicKey instanceof DSAPublicKey) {
// create and append DSAKeyValue element
marshalDSAPublicKey(parent, doc, dsPrefix, context);
} else if (publicKey instanceof RSAPublicKey) {
// create and append RSAKeyValue element
marshalRSAPublicKey(parent, doc, dsPrefix, context);
} else {
throw new MarshalException(publicKey.getAlgorithm() +
" public key algorithm not supported");
}
} else {
parent.appendChild(externalPublicKey.getNode());
}
}
private void marshalDSAPublicKey(Node parent, Document doc,
String dsPrefix, DOMCryptoContext context) throws MarshalException {
Element dsaElem = DOMUtils.createElement
(doc, "DSAKeyValue", XMLSignature.XMLNS, dsPrefix);
// parameters J, Seed & PgenCounter are not included
Element pElem = DOMUtils.createElement
(doc, "P", XMLSignature.XMLNS, dsPrefix);
Element qElem = DOMUtils.createElement
(doc, "Q", XMLSignature.XMLNS, dsPrefix);
Element gElem = DOMUtils.createElement
(doc, "G", XMLSignature.XMLNS, dsPrefix);
Element yElem = DOMUtils.createElement
(doc, "Y", XMLSignature.XMLNS, dsPrefix);
p.marshal(pElem, dsPrefix, context);
q.marshal(qElem, dsPrefix, context);
g.marshal(gElem, dsPrefix, context);
y.marshal(yElem, dsPrefix, context);
dsaElem.appendChild(pElem);
dsaElem.appendChild(qElem);
dsaElem.appendChild(gElem);
dsaElem.appendChild(yElem);
parent.appendChild(dsaElem);
}
private void marshalRSAPublicKey(Node parent, Document doc,
String dsPrefix, DOMCryptoContext context) throws MarshalException {
Element rsaElem = DOMUtils.createElement
(doc, "RSAKeyValue", XMLSignature.XMLNS, dsPrefix);
Element modulusElem = DOMUtils.createElement
(doc, "Modulus", XMLSignature.XMLNS, dsPrefix);
Element exponentElem = DOMUtils.createElement
(doc, "Exponent", XMLSignature.XMLNS, dsPrefix);
modulus.marshal(modulusElem, dsPrefix, context);
exponent.marshal(exponentElem, dsPrefix, context);
rsaElem.appendChild(modulusElem);
rsaElem.appendChild(exponentElem);
parent.appendChild(rsaElem);
}
private DSAPublicKey unmarshalDSAKeyValue(Element kvtElem)
throws MarshalException {
if (dsakf == null) {
try {
dsakf = KeyFactory.getInstance("DSA");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("unable to create DSA KeyFactory: " +
e.getMessage());
}
}
Element curElem = DOMUtils.getFirstChildElement(kvtElem);
// check for P and Q
if (curElem.getLocalName().equals("P")) {
p = new DOMCryptoBinary(curElem.getFirstChild());
curElem = DOMUtils.getNextSiblingElement(curElem);
q = new DOMCryptoBinary(curElem.getFirstChild());
curElem = DOMUtils.getNextSiblingElement(curElem);
}
if (curElem.getLocalName().equals("G")) {
g = new DOMCryptoBinary(curElem.getFirstChild());
curElem = DOMUtils.getNextSiblingElement(curElem);
}
y = new DOMCryptoBinary(curElem.getFirstChild());
curElem = DOMUtils.getNextSiblingElement(curElem);
if (curElem != null && curElem.getLocalName().equals("J")) {
j = new DOMCryptoBinary(curElem.getFirstChild());
curElem = DOMUtils.getNextSiblingElement(curElem);
}
if (curElem != null) {
seed = new DOMCryptoBinary(curElem.getFirstChild());
curElem = DOMUtils.getNextSiblingElement(curElem);
pgen = new DOMCryptoBinary(curElem.getFirstChild());
}
//@@@ do we care about j, pgenCounter or seed?
DSAPublicKeySpec spec = new DSAPublicKeySpec
(y.getBigNum(), p.getBigNum(), q.getBigNum(), g.getBigNum());
return (DSAPublicKey) generatePublicKey(dsakf, spec);
}
private RSAPublicKey unmarshalRSAKeyValue(Element kvtElem)
throws MarshalException {
if (rsakf == null) {
try {
rsakf = KeyFactory.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("unable to create RSA KeyFactory: " +
e.getMessage());
}
}
Element modulusElem = DOMUtils.getFirstChildElement(kvtElem);
modulus = new DOMCryptoBinary(modulusElem.getFirstChild());
Element exponentElem = DOMUtils.getNextSiblingElement(modulusElem);
exponent = new DOMCryptoBinary(exponentElem.getFirstChild());
RSAPublicKeySpec spec = new RSAPublicKeySpec
(modulus.getBigNum(), exponent.getBigNum());
return (RSAPublicKey) generatePublicKey(rsakf, spec);
}
private PublicKey generatePublicKey(KeyFactory kf, KeySpec keyspec) {
try {
return kf.generatePublic(keyspec);
} catch (InvalidKeySpecException e) {
//@@@ should dump exception to log
return null;
}
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof KeyValue)) {
return false;
}
try {
KeyValue kv = (KeyValue) obj;
if (publicKey == null ) {
if (kv.getPublicKey() != null) {
return false;
}
} else if (!publicKey.equals(kv.getPublicKey())) {
return false;
}
} catch (KeyException ke) {
// no practical way to determine if the keys are equal
return false;
}
return true;
}
}