001: /*
002: * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.security.mscapi;
027:
028: import java.math.BigInteger;
029: import java.security.InvalidKeyException;
030: import java.security.KeyRep;
031: import java.security.PublicKey;
032:
033: import sun.security.rsa.RSAPublicKeyImpl;
034:
035: /**
036: * The handle for an RSA public key using the Microsoft Crypto API.
037: *
038: * @since 1.6
039: */
040: class RSAPublicKey extends Key implements
041: java.security.interfaces.RSAPublicKey {
042: private byte[] publicKeyBlob = null;
043: private byte[] encoding = null;
044: private BigInteger modulus = null;
045: private BigInteger exponent = null;
046:
047: /**
048: * Construct an RSAPublicKey object.
049: */
050: RSAPublicKey(long hCryptProv, long hCryptKey, int keyLength) {
051: super (hCryptProv, hCryptKey, keyLength);
052: }
053:
054: /**
055: * Returns the standard algorithm name for this key. For
056: * example, "RSA" would indicate that this key is a RSA key.
057: * See Appendix A in the <a href=
058: * "../../../guide/security/CryptoSpec.html#AppA">
059: * Java Cryptography Architecture API Specification & Reference </a>
060: * for information about standard algorithm names.
061: *
062: * @return the name of the algorithm associated with this key.
063: */
064: public String getAlgorithm() {
065: return "RSA";
066: }
067:
068: /**
069: * Returns a printable description of the key.
070: */
071: public String toString() {
072: StringBuffer sb = new StringBuffer();
073:
074: sb.append("RSAPublicKey [size=").append(keyLength).append(
075: " bits, type=").append(getKeyType(hCryptKey)).append(
076: ", container=").append(getContainerName(hCryptProv))
077: .append("]\n modulus: ").append(getModulus()).append(
078: "\n public exponent: ").append(
079: getPublicExponent());
080:
081: return sb.toString();
082: }
083:
084: /**
085: * Returns the public exponent.
086: */
087: public BigInteger getPublicExponent() {
088:
089: if (exponent == null) {
090: publicKeyBlob = getPublicKeyBlob(hCryptKey);
091:
092: exponent = new BigInteger(getExponent(publicKeyBlob));
093: }
094:
095: return exponent;
096: }
097:
098: /**
099: * Returns the modulus.
100: */
101: public BigInteger getModulus() {
102:
103: if (modulus == null) {
104: publicKeyBlob = getPublicKeyBlob(hCryptKey);
105: modulus = new BigInteger(getModulus(publicKeyBlob));
106: }
107:
108: return modulus;
109: }
110:
111: /**
112: * Returns the name of the primary encoding format of this key,
113: * or null if this key does not support encoding.
114: * The primary encoding format is
115: * named in terms of the appropriate ASN.1 data format, if an
116: * ASN.1 specification for this key exists.
117: * For example, the name of the ASN.1 data format for public
118: * keys is <I>SubjectPublicKeyInfo</I>, as
119: * defined by the X.509 standard; in this case, the returned format is
120: * <code>"X.509"</code>. Similarly,
121: * the name of the ASN.1 data format for private keys is
122: * <I>PrivateKeyInfo</I>,
123: * as defined by the PKCS #8 standard; in this case, the returned format is
124: * <code>"PKCS#8"</code>.
125: *
126: * @return the primary encoding format of the key.
127: */
128: public String getFormat() {
129: return "X.509";
130: }
131:
132: /**
133: * Returns the key in its primary encoding format, or null
134: * if this key does not support encoding.
135: *
136: * @return the encoded key, or null if the key does not support
137: * encoding.
138: */
139: public byte[] getEncoded() {
140: if (encoding == null) {
141:
142: try {
143: encoding = new RSAPublicKeyImpl(getModulus(),
144: getPublicExponent()).getEncoded();
145:
146: } catch (InvalidKeyException e) {
147: // ignore
148: }
149: }
150: return encoding;
151: }
152:
153: protected Object writeReplace()
154: throws java.io.ObjectStreamException {
155: return new KeyRep(KeyRep.Type.PUBLIC, getAlgorithm(),
156: getFormat(), getEncoded());
157: }
158:
159: /*
160: * Returns the Microsoft CryptoAPI representation of the key.
161: */
162: private native byte[] getPublicKeyBlob(long hCryptKey);
163:
164: /*
165: * Returns the key's public exponent (in big-endian 2's complement format).
166: */
167: private native byte[] getExponent(byte[] keyBlob);
168:
169: /*
170: * Returns the key's modulus (in big-endian 2's complement format).
171: */
172: private native byte[] getModulus(byte[] keyBlob);
173: }
|