/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Key implementation classes.
*
* In PKCS#11, the components of private and secret keys may or may not
* be accessible. If they are, we use the algorithm specific key classes
* (e.g. DSAPrivateKey) for compatibility with existing applications.
* If the components are not accessible, we use a generic class that
* only implements PrivateKey (or SecretKey). Whether the components of a
* key are extractable is automatically determined when the key object is
* created.
*
* @author Andreas Sterbenz
* @since 1.5
*/
// type of key, one of (PUBLIC, PRIVATE, SECRET)
// token instance
// algorithm name, returned by getAlgorithm(), etc.
// key id
final long keyID;
// effective key length of the key, e.g. 56 for a DES key
final int keyLength;
// flags indicating whether the key is a token object, sensitive, extractable
// phantom reference notification clean up for session keys
boolean tokenObject = false;
boolean sensitive = false;
boolean extractable = true;
for (int i = 0; i < n; i++) {
}
}
this.tokenObject = tokenObject;
this.extractable = extractable;
if (tokenObject == false) {
} else {
}
}
// see JCA spec
token.ensureValid();
return algorithm;
}
// see JCA spec
public final byte[] getEncoded() {
byte[] b = getEncodedInternal();
}
abstract byte[] getEncodedInternal();
if (this == obj) {
return true;
}
// equals() should never throw exceptions
return false;
}
return false;
}
if (thisFormat == null) {
// no encoding, key only equal to itself
// XXX getEncoded() for unextractable keys will change that
return false;
}
return false;
}
byte[] thisEnc = this.getEncodedInternal();
byte[] otherEnc;
} else {
}
}
public int hashCode() {
// hashCode() should never throw exceptions
return 0;
}
byte[] b1 = getEncodedInternal();
return 0;
}
}
return r;
}
} else {
// XXX short term serialization for unextractable keys
throw new NotSerializableException
("Cannot serialize sensitive and unextractable keys");
}
}
token.ensureValid();
if (isPublic()) {
s1 += ")";
} else {
}
return s1;
}
/**
* Return bit length of the key.
*/
public int length() {
return keyLength;
}
boolean isPublic() {
}
boolean isPrivate() {
}
boolean isSecret() {
}
try {
} catch (PKCS11Exception e) {
throw new ProviderException(e);
} finally {
}
}
if (knownAttributes == null) {
}
// For each desired attribute, check to see if we have the value
// available already. If everything is here, we save a native call.
break; // break inner for loop
}
}
// nothing found, need to call C_GetAttributeValue()
for (int j = 0; j < i; j++) {
// clear values copied from knownAttributes
}
try {
} catch (PKCS11Exception e) {
throw new ProviderException(e);
}
break; // break loop, goto return
}
}
return desiredAttributes;
}
new CK_ATTRIBUTE(CKA_TOKEN),
new CK_ATTRIBUTE(CKA_SENSITIVE),
new CK_ATTRIBUTE(CKA_EXTRACTABLE),
});
}
new CK_ATTRIBUTE(CKA_TOKEN),
new CK_ATTRIBUTE(CKA_SENSITIVE),
new CK_ATTRIBUTE(CKA_EXTRACTABLE),
});
return new P11TlsMasterSecretKey
}
// we assume that all components of public keys are always accessible
return new P11RSAPublicKey
return new P11DSAPublicKey
return new P11DHPublicKey
return new P11ECPublicKey
} else {
throw new ProviderException
("Unknown public key algorithm " + algorithm);
}
}
new CK_ATTRIBUTE(CKA_TOKEN),
new CK_ATTRIBUTE(CKA_SENSITIVE),
new CK_ATTRIBUTE(CKA_EXTRACTABLE),
});
return new P11PrivateKey
} else {
// XXX better test for RSA CRT keys (single getAttributes() call)
// we need to determine whether this is a CRT key
// see if we can obtain the public exponent
// this should also be readable for sensitive/extractable keys
};
boolean crtKey;
try {
} catch (PKCS11Exception e) {
// ignore, assume not available
crtKey = false;
}
if (crtKey) {
return new P11RSAPrivateKey
} else {
return new P11RSAPrivateNonCRTKey
}
return new P11DSAPrivateKey
return new P11DHPrivateKey
return new P11ECPrivateKey
} else {
throw new ProviderException
("Unknown private key algorithm " + algorithm);
}
}
}
// class for sensitive and unextractable private keys
implements PrivateKey {
}
// XXX temporary encoding for serialization purposes
token.ensureValid();
return null;
}
byte[] getEncodedInternal() {
token.ensureValid();
return null;
}
}
private volatile byte[] encoded;
}
token.ensureValid();
if (sensitive || (extractable == false)) {
return null;
} else {
return "RAW";
}
}
byte[] getEncodedInternal() {
token.ensureValid();
return null;
}
byte[] b = encoded;
if (b == null) {
synchronized (this) {
b = encoded;
if (b == null) {
try {
new CK_ATTRIBUTE(CKA_VALUE),
};
} catch (PKCS11Exception e) {
throw new ProviderException(e);
} finally {
}
encoded = b;
}
}
}
return b;
}
}
implements TlsMasterSecret {
this.majorVersion = major;
this.minorVersion = minor;
}
public int getMajorVersion() {
return majorVersion;
}
public int getMinorVersion() {
return minorVersion;
}
}
// RSA CRT private key
implements RSAPrivateCrtKey {
private byte[] encoded;
}
private synchronized void fetchValues() {
token.ensureValid();
if (n != null) {
return;
}
new CK_ATTRIBUTE(CKA_MODULUS),
new CK_ATTRIBUTE(CKA_PRIME_1),
new CK_ATTRIBUTE(CKA_PRIME_2),
new CK_ATTRIBUTE(CKA_EXPONENT_1),
new CK_ATTRIBUTE(CKA_EXPONENT_2),
new CK_ATTRIBUTE(CKA_COEFFICIENT),
};
}
token.ensureValid();
return "PKCS#8";
}
synchronized byte[] getEncodedInternal() {
token.ensureValid();
fetchValues();
try {
// XXX make constructor in SunRsaSign provider public
// and call it directly
} catch (GeneralSecurityException e) {
throw new ProviderException(e);
}
}
return encoded;
}
fetchValues();
return n;
}
fetchValues();
return e;
}
fetchValues();
return d;
}
fetchValues();
return p;
}
fetchValues();
return q;
}
fetchValues();
return pe;
}
fetchValues();
return qe;
}
fetchValues();
return coeff;
}
fetchValues();
}
}
// RSA non-CRT private key
implements RSAPrivateKey {
private BigInteger n, d;
private byte[] encoded;
}
private synchronized void fetchValues() {
token.ensureValid();
if (n != null) {
return;
}
new CK_ATTRIBUTE(CKA_MODULUS),
};
}
token.ensureValid();
return "PKCS#8";
}
synchronized byte[] getEncodedInternal() {
token.ensureValid();
fetchValues();
try {
// XXX make constructor in SunRsaSign provider public
// and call it directly
} catch (GeneralSecurityException e) {
throw new ProviderException(e);
}
}
return encoded;
}
fetchValues();
return n;
}
fetchValues();
return d;
}
fetchValues();
}
}
implements RSAPublicKey {
private BigInteger n, e;
private byte[] encoded;
}
private synchronized void fetchValues() {
token.ensureValid();
if (n != null) {
return;
}
new CK_ATTRIBUTE(CKA_MODULUS),
};
}
token.ensureValid();
return "X.509";
}
synchronized byte[] getEncodedInternal() {
token.ensureValid();
fetchValues();
try {
} catch (InvalidKeyException e) {
throw new ProviderException(e);
}
}
return encoded;
}
fetchValues();
return n;
}
fetchValues();
return e;
}
fetchValues();
return super.toString() + "\n modulus: " + n
+ "\n public exponent: " + e;
}
}
implements DSAPublicKey {
private BigInteger y;
private byte[] encoded;
}
private synchronized void fetchValues() {
token.ensureValid();
if (y != null) {
return;
}
new CK_ATTRIBUTE(CKA_VALUE),
new CK_ATTRIBUTE(CKA_PRIME),
new CK_ATTRIBUTE(CKA_SUBPRIME),
new CK_ATTRIBUTE(CKA_BASE),
};
params = new DSAParameterSpec(
);
}
token.ensureValid();
return "X.509";
}
synchronized byte[] getEncodedInternal() {
token.ensureValid();
fetchValues();
try {
} catch (InvalidKeyException e) {
throw new ProviderException(e);
}
}
return encoded;
}
fetchValues();
return y;
}
fetchValues();
return params;
}
fetchValues();
}
}
implements DSAPrivateKey {
private BigInteger x;
private byte[] encoded;
}
private synchronized void fetchValues() {
token.ensureValid();
if (x != null) {
return;
}
new CK_ATTRIBUTE(CKA_VALUE),
new CK_ATTRIBUTE(CKA_PRIME),
new CK_ATTRIBUTE(CKA_SUBPRIME),
new CK_ATTRIBUTE(CKA_BASE),
};
params = new DSAParameterSpec(
);
}
token.ensureValid();
return "PKCS#8";
}
synchronized byte[] getEncodedInternal() {
token.ensureValid();
fetchValues();
try {
} catch (InvalidKeyException e) {
throw new ProviderException(e);
}
}
return encoded;
}
fetchValues();
return x;
}
fetchValues();
return params;
}
fetchValues();
}
}
implements DHPrivateKey {
private BigInteger x;
private byte[] encoded;
}
private synchronized void fetchValues() {
token.ensureValid();
if (x != null) {
return;
}
new CK_ATTRIBUTE(CKA_VALUE),
new CK_ATTRIBUTE(CKA_PRIME),
new CK_ATTRIBUTE(CKA_BASE),
};
params = new DHParameterSpec(
);
}
token.ensureValid();
return "PKCS#8";
}
synchronized byte[] getEncodedInternal() {
token.ensureValid();
fetchValues();
try {
} catch (GeneralSecurityException e) {
throw new ProviderException(e);
}
}
return encoded;
}
fetchValues();
return x;
}
fetchValues();
return params;
}
fetchValues();
}
}
implements DHPublicKey {
private BigInteger y;
private byte[] encoded;
}
private synchronized void fetchValues() {
token.ensureValid();
if (y != null) {
return;
}
new CK_ATTRIBUTE(CKA_VALUE),
new CK_ATTRIBUTE(CKA_PRIME),
new CK_ATTRIBUTE(CKA_BASE),
};
params = new DHParameterSpec(
);
}
token.ensureValid();
return "X.509";
}
synchronized byte[] getEncodedInternal() {
token.ensureValid();
fetchValues();
try {
} catch (GeneralSecurityException e) {
throw new ProviderException(e);
}
}
return encoded;
}
fetchValues();
return y;
}
fetchValues();
return params;
}
fetchValues();
}
}
implements ECPrivateKey {
private BigInteger s;
private byte[] encoded;
}
private synchronized void fetchValues() {
token.ensureValid();
if (s != null) {
return;
}
new CK_ATTRIBUTE(CKA_VALUE),
};
try {
} catch (Exception e) {
throw new RuntimeException("Could not parse key values", e);
}
}
token.ensureValid();
return "PKCS#8";
}
synchronized byte[] getEncodedInternal() {
token.ensureValid();
fetchValues();
try {
} catch (InvalidKeyException e) {
throw new ProviderException(e);
}
}
return encoded;
}
fetchValues();
return s;
}
fetchValues();
return params;
}
fetchValues();
return super.toString()
+ "\n private value: " + s
+ "\n parameters: " + params;
}
}
implements ECPublicKey {
private ECPoint w;
private byte[] encoded;
}
private synchronized void fetchValues() {
token.ensureValid();
if (w != null) {
return;
}
new CK_ATTRIBUTE(CKA_EC_POINT),
new CK_ATTRIBUTE(CKA_EC_PARAMS),
};
try {
// Check whether the X9.63 encoding of an EC point is wrapped
// in an ASN.1 OCTET STRING
throw new IOException("Could not DER decode EC point." +
}
} else {
}
} catch (Exception e) {
throw new RuntimeException("Could not parse key values", e);
}
}
token.ensureValid();
return "X.509";
}
synchronized byte[] getEncodedInternal() {
token.ensureValid();
fetchValues();
try {
} catch (InvalidKeyException e) {
throw new ProviderException(e);
}
}
return encoded;
}
fetchValues();
return w;
}
fetchValues();
return params;
}
fetchValues();
return super.toString()
+ "\n public x coord: " + w.getAffineX()
+ "\n public y coord: " + w.getAffineY()
+ "\n parameters: " + params;
}
}
}
/*
* NOTE: Must use PhantomReference here and not WeakReference
* otherwise the key maybe cleared before other objects which
* still use these keys during finalization such as SSLSocket.
*/
implements Comparable<SessionKeyRef> {
new ReferenceQueue<P11Key>();
return refQueue;
}
private static void drainRefQueueBounded() {
while (true) {
}
}
// handle to the native key
private long keyID;
// TBD: run at some interval and not every time?
}
private void dispose() {
try {
} catch (PKCS11Exception e) {
// ignore
} finally {
this.clear();
}
}
}
return 0;
} else {
}
}
}