1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 package org.apache.ws.security.components.crypto;
21
22 import java.security.PublicKey;
23 import org.apache.ws.security.WSSecurityException;
24
25 /**
26 * Represents the X.509 SubjectPublicKeyInfo for a public key, as specified
27 * in RFC3280/5280:
28 * <pre>
29 * SubjectPublicKeyInfo ::= SEQUENCE {
30 * algorithm AlgorithmIdentifier,
31 * subjectPublicKey BIT STRING }
32 *
33 * AlgorithmIdentifier ::= SEQUENCE {
34 * algorithm OBJECT IDENTIFIER,
35 * parameters ANY DEFINED BY algorithm OPTIONAL }
36 * </pre>
37 */
38 public class X509SubjectPublicKeyInfo extends DERDecoder {
39
40 /**
41 * Construct a SubjectPublicKeyInfo for the given public key.
42 *
43 * @param key the public key.
44 * @throws WSSecurityException if the public key encoding format is
45 * not X.509 or the encoding is null.
46 */
47 public X509SubjectPublicKeyInfo(PublicKey key) throws WSSecurityException {
48 super(key.getEncoded());
49 if (!("X.509".equalsIgnoreCase(key.getFormat())
50 || "X509".equalsIgnoreCase(key.getFormat()))) {
51 throw new WSSecurityException(
52 WSSecurityException.UNSUPPORTED_SECURITY_TOKEN,
53 "noSKIHandling",
54 new Object[] { "Support for X.509-encoded public keys only" }
55 );
56 }
57 }
58
59 /**
60 * Construct a SubjectPublicKeyInfo for the given X.509-encoded public key.
61 *
62 * @param x509EncodedPublicKey the public key, in X.509 DER-encoding.
63 * @throws WSSecurityException if the encoded public key is null.
64 */
65 public X509SubjectPublicKeyInfo(byte[] x509EncodedPublicKey) throws WSSecurityException {
66 super(x509EncodedPublicKey);
67 }
68
69 /**
70 * Get the subjectPublicKey element of the SubjectPublicKeyInfo.
71 *
72 * @return the X.509-encoded subjectPublicKey bit string.
73 * @throws WSSecurityException the DER-encoding is invalid.
74 */
75 public byte[] getSubjectPublicKey() throws WSSecurityException {
76 reset();
77 expect(TYPE_SEQUENCE); // SubjectPublicKeyInfo SEQUENCE
78 getLength();
79 // Could enforce the max length of this sequence, but not actually
80 // necessary for our purposes, so be forgiving and simply ignore.
81 expect(TYPE_SEQUENCE); // algorithm AlgorithmIdentifier SEQUENCE
82 int algIDlen = getLength();
83 if (algIDlen < 0) {
84 // Unsupported indefinite-length
85 throw new WSSecurityException(
86 WSSecurityException.UNSUPPORTED_SECURITY_TOKEN,
87 "noSKIHandling",
88 new Object[] { "Unsupported X.509 public key format" }
89 );
90 }
91 skip(algIDlen); // AlgorithmIdentifier contents
92 expect(TYPE_BIT_STRING); // subjectPublicKey BIT STRING
93 int keyLen = getLength()-1;
94 if (keyLen < 0) {
95 // Invalid BIT STRING length
96 throw new WSSecurityException(
97 WSSecurityException.UNSUPPORTED_SECURITY_TOKEN,
98 "noSKIHandling",
99 new Object[] { "Invalid X.509 public key format" }
100 );
101 }
102 skip(1); // number unused bits
103 // DER-encoding guarantees unused bits should be 0
104
105 return getBytes(keyLen);
106 }
107 }