|
1 /* |
|
2 * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 package sun.security.mscapi; |
|
27 |
|
28 import java.math.BigInteger; |
|
29 import java.security.KeyException; |
|
30 import java.security.KeyRep; |
|
31 import java.security.ProviderException; |
|
32 import java.security.PublicKey; |
|
33 import java.security.interfaces.RSAPublicKey; |
|
34 |
|
35 import sun.security.rsa.RSAUtil.KeyType; |
|
36 import sun.security.rsa.RSAPublicKeyImpl; |
|
37 |
|
38 /** |
|
39 * The handle for an RSA public key using the Microsoft Crypto API. |
|
40 * |
|
41 * @since 1.6 |
|
42 */ |
|
43 public abstract class CPublicKey extends CKey implements PublicKey { |
|
44 |
|
45 private static final long serialVersionUID = -2289561342425825391L; |
|
46 |
|
47 protected byte[] publicKeyBlob = null; |
|
48 protected byte[] encoding = null; |
|
49 |
|
50 public static class CRSAPublicKey extends CPublicKey implements RSAPublicKey { |
|
51 |
|
52 private BigInteger modulus = null; |
|
53 private BigInteger exponent = null; |
|
54 private static final long serialVersionUID = 12L; |
|
55 |
|
56 CRSAPublicKey(long hCryptProv, long hCryptKey, int keyLength) { |
|
57 super("RSA", hCryptProv, hCryptKey, keyLength); |
|
58 } |
|
59 |
|
60 public String toString() { |
|
61 StringBuffer sb = new StringBuffer(); |
|
62 sb.append(algorithm + "PublicKey [size=").append(keyLength) |
|
63 .append(" bits, type=").append(getKeyType(handles.hCryptKey)) |
|
64 .append(", container=").append(getContainerName(handles.hCryptProv)) |
|
65 .append("]\n modulus: ").append(getModulus()) |
|
66 .append("\n public exponent: ").append(getPublicExponent()); |
|
67 return sb.toString(); |
|
68 } |
|
69 |
|
70 @Override |
|
71 public BigInteger getPublicExponent() { |
|
72 if (exponent == null) { |
|
73 try { |
|
74 publicKeyBlob = getPublicKeyBlob(handles.hCryptKey); |
|
75 exponent = new BigInteger(1, getExponent(publicKeyBlob)); |
|
76 } catch (KeyException e) { |
|
77 throw new ProviderException(e); |
|
78 } |
|
79 } |
|
80 return exponent; |
|
81 } |
|
82 |
|
83 @Override |
|
84 public BigInteger getModulus() { |
|
85 if (modulus == null) { |
|
86 try { |
|
87 publicKeyBlob = getPublicKeyBlob(handles.hCryptKey); |
|
88 modulus = new BigInteger(1, getModulus(publicKeyBlob)); |
|
89 } catch (KeyException e) { |
|
90 throw new ProviderException(e); |
|
91 } |
|
92 } |
|
93 return modulus; |
|
94 } |
|
95 |
|
96 @Override |
|
97 public byte[] getEncoded() { |
|
98 if (encoding == null) { |
|
99 try { |
|
100 encoding = RSAPublicKeyImpl.newKey(KeyType.RSA, null, |
|
101 getModulus(), getPublicExponent()).getEncoded(); |
|
102 } catch (KeyException e) { |
|
103 // ignore |
|
104 } |
|
105 } |
|
106 return encoding; |
|
107 } |
|
108 |
|
109 private native byte[] getExponent(byte[] keyBlob) throws KeyException; |
|
110 |
|
111 private native byte[] getModulus(byte[] keyBlob) throws KeyException; |
|
112 } |
|
113 |
|
114 public static CPublicKey of(String alg, long hCryptProv, long hCryptKey, int keyLength) { |
|
115 switch (alg) { |
|
116 case "RSA": |
|
117 return new CRSAPublicKey(hCryptProv, hCryptKey, keyLength); |
|
118 default: |
|
119 throw new AssertionError("Unsupported algorithm: " + alg); |
|
120 } |
|
121 } |
|
122 |
|
123 protected CPublicKey(String alg, long hCryptProv, long hCryptKey, int keyLength) { |
|
124 super(alg, hCryptProv, hCryptKey, keyLength); |
|
125 } |
|
126 |
|
127 @Override |
|
128 public String getFormat() { |
|
129 return "X.509"; |
|
130 } |
|
131 |
|
132 protected Object writeReplace() throws java.io.ObjectStreamException { |
|
133 return new KeyRep(KeyRep.Type.PUBLIC, |
|
134 getAlgorithm(), |
|
135 getFormat(), |
|
136 getEncoded()); |
|
137 } |
|
138 |
|
139 // Returns the Microsoft CryptoAPI representation of the key. |
|
140 native byte[] getPublicKeyBlob(long hCryptKey) throws KeyException; |
|
141 |
|
142 } |