API Overview API Index Package Overview Direct link to this page
JDK 1.6
  org.jcp.xml.dsig.internal.dom. DOMKeyValue View Javadoc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

/*
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 */
/*
 * $Id: DOMKeyValue.java,v 1.18 2005/05/10 18:15:33 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;
    }
}

Generated By: JavaOnTracks Doclet 0.1.4     ©Thibaut Colar