libjss.so
on UNIX, jss.dll
on Windows) and a ZIP file
(jss.zip
) containing system-independent Java classes.
These classes are compatible with JDK 1.1 or later using the native
thread implementation (not green threads).
jss.zip
in your
CLASSPATH
.
libjss.so
in your
LD_LIBRARY_PATH
(on UNIX) or jss.dll
in your PATH
(on Windows), and put
jss.zip
in your CLASSPATH
.
NSSInit.initialize
must be called to open the security
databases and initialize the random number generator.
NSSInit.setPasswordCallback
may be called to change the password
callback; the default is to prompt for passwords on the command line.
The files in the examples
directory illustrate the use of JSS
in an application:
cert7.db
and key3.db
files, also in the
examples
directory,
can be used for this purpose. When SSLServer
is run,
it will ask for a password
for the "Internal Key Storage Token", which is the key database.
The password for the example key3.db
file is "netscape".
org.mozilla.jss.ssl
package.
The .class
files must be put in the subdirectory
org/mozilla/jss/ssl
of a CLASSPATH
entry
in order to be located by the Java virtual machine.
CryptoToken.login
.
* The default is a ConsolePasswordCallback
.
*/
public PasswordCallback passwordCallback =
new ConsolePasswordCallback();
/**
* The FIPS mode of the security library. Servers should
* use FIPSMode.UNCHANGED
, since only
* Admin Server is supposed to alter this value.
*
The default is FIPSMode.UNCHANGED
.
*/
public FIPSMode fipsMode = FIPSMode.UNCHANGED;
/**
* To open the databases in read-only mode, set this flag to
* true
. The default is false
, meaning
* the databases are opened in read-write mode.
*/
public boolean readOnly = false;
////////////////////////////////////////////////////////////////////
// Manufacturer ID
////////////////////////////////////////////////////////////////////
/**
* Returns the Manufacturer ID of the internal PKCS #11 module.
*
The default is "mozilla.org "
.
*/
public String getManufacturerID() { return manufacturerID; }
/**
* Sets the Manufacturer ID of the internal PKCS #11 module.
* This value must be exactly MANUFACTURER_LENGTH
* characters long.
* @exception InvalidLengthException If s.length()
is not
* exactly MANUFACTURER_LENGTH
.
*/
public void setManufacturerID(String s) throws InvalidLengthException {
if( s.length() != MANUFACTURER_LENGTH ) {
throw new InvalidLengthException();
}
manufacturerID = s;
}
private String manufacturerID =
"mozilla.org ";
////////////////////////////////////////////////////////////////////
// Library Description
////////////////////////////////////////////////////////////////////
/**
* Returns the description of the internal PKCS #11 module.
*
The default is "Internal Crypto Services "
.
*/
public String getLibraryDescription() { return libraryDescription; }
/**
* Sets the description of the internal PKCS #11 module.
* This value must be exactly LIBRARY_LENGTH
* characters long.
* @exception InvalidLengthException If s.length()
is
* not exactly LIBRARY_LENGTH
.
*/
public void setLibraryDescription(String s)
throws InvalidLengthException
{
if( s.length() != LIBRARY_LENGTH ) {
throw new InvalidLengthException();
}
libraryDescription = s;
}
private String libraryDescription =
"Internal Crypto Services ";
////////////////////////////////////////////////////////////////////
// Internal Token Description
////////////////////////////////////////////////////////////////////
/**
* Returns the description of the internal PKCS #11 token.
*
The default is "Internal Crypto Services Token "
.
*/
public String getInternalTokenDescription() {
return internalTokenDescription;
}
/**
* Sets the description of the internal PKCS #11 token.
* This value must be exactly TOKEN_LENGTH
characters long.
* @exception InvalidLengthException If s.length()
is
* not exactly TOKEN_LENGTH
.
*/
public void setInternalTokenDescription(String s)
throws InvalidLengthException
{
if(s.length() != TOKEN_LENGTH) {
throw new InvalidLengthException();
}
internalTokenDescription = s;
}
private String internalTokenDescription =
"NSS Generic Crypto Services ";
////////////////////////////////////////////////////////////////////
// Internal Key Storage Token Description
////////////////////////////////////////////////////////////////////
/**
* Returns the description of the internal PKCS #11 key storage token.
*
The default is "Internal Key Storage Token "
.
*/
public String getInternalKeyStorageTokenDescription() {
return internalKeyStorageTokenDescription;
}
/**
* Sets the description of the internal PKCS #11 key storage token.
* This value must be exactly TOKEN_LENGTH
characters long.
* @exception InvalidLengthException If s.length()
is
* not exactly TOKEN_LENGTH
.
*/
public void setInternalKeyStorageTokenDescription(String s)
throws InvalidLengthException
{
if(s.length() != TOKEN_LENGTH) {
throw new InvalidLengthException();
}
internalKeyStorageTokenDescription = s;
}
private String internalKeyStorageTokenDescription =
"Internal Key Storage Token ";
////////////////////////////////////////////////////////////////////
// Internal Slot Description
////////////////////////////////////////////////////////////////////
/**
* Returns the description of the internal PKCS #11 slot.
*
The default is "NSS Internal Cryptographic Services "
.
*/
public String getInternalSlotDescription() {
return internalSlotDescription;
}
/**
* Sets the description of the internal PKCS #11 slot.
* This value must be exactly SLOT_LENGTH
characters
* long.
* @exception InvalidLengthException If s.length()
is
* not exactly SLOT_LENGTH
.
*/
public void setInternalSlotDescription(String s)
throws InvalidLengthException
{
if(s.length() != SLOT_LENGTH) {
throw new InvalidLengthException();
}
internalSlotDescription = s;
}
private String internalSlotDescription =
"NSS Internal Cryptographic Services ";
////////////////////////////////////////////////////////////////////
// Internal Key Storage Slot Description
////////////////////////////////////////////////////////////////////
/**
* Returns the description of the internal PKCS #11 key storage slot.
*
The default is "NSS Internal Private Key and Certificate Storage "
.
*/
public String getInternalKeyStorageSlotDescription() {
return internalKeyStorageSlotDescription;
}
/**
* Sets the description of the internal PKCS #11 key storage slot.
* This value must be exactly SLOT_LENGTH
characters
* long.
* @exception InvalidLengthException If s.length()
is
* not exactly SLOT_LENGTH
.
*/
public void setInternalKeyStorageSlotDescription(String s)
throws InvalidLengthException
{
if(s.length() != SLOT_LENGTH) {
throw new InvalidLengthException();
}
internalKeyStorageSlotDescription = s;
}
private String internalKeyStorageSlotDescription =
"NSS User Private Key and Certificate Services ";
////////////////////////////////////////////////////////////////////
// FIPS Slot Description
////////////////////////////////////////////////////////////////////
/**
* Returns the description of the internal PKCS #11 FIPS slot.
*
The default is
* "NSS FIPS 140-2 User Private Key Services"
.
*/
public String getFIPSSlotDescription() {
return FIPSSlotDescription;
}
/**
* Sets the description of the internal PKCS #11 FIPS slot.
* This value must be exactly SLOT_LENGTH
characters
* long.
* @exception InvalidLengthException If s.length()
is
* not exactly SLOT_LENGTH
.
*/
public void setFIPSSlotDescription(String s)
throws InvalidLengthException
{
if(s.length() != SLOT_LENGTH) {
throw new InvalidLengthException();
}
FIPSSlotDescription = s;
}
private String FIPSSlotDescription =
"NSS FIPS 140-2 User Private Key Services ";
////////////////////////////////////////////////////////////////////
// FIPS Key Storage Slot Description
////////////////////////////////////////////////////////////////////
/**
* Returns the description of the internal PKCS #11 FIPS
* Key Storage slot.
*
The default is
* "NSS FIPS 140-2 User Private Key Services"
.
*/
public String getFIPSKeyStorageSlotDescription() {
return FIPSKeyStorageSlotDescription;
}
/**
* Sets the description of the internal PKCS #11 FIPS Key Storage slot.
* This value must be exactly SLOT_LENGTH
characters
* long.
* @exception InvalidLengthException If s.length()
is
* not exactly SLOT_LENGTH
.
*/
public void setFIPSKeyStorageSlotDescription(String s)
throws InvalidLengthException
{
if(s.length() != SLOT_LENGTH) {
throw new InvalidLengthException();
}
FIPSKeyStorageSlotDescription = s;
}
private String FIPSKeyStorageSlotDescription =
"NSS FIPS 140-2 User Private Key Services ";
/**
* To have NSS check the OCSP responder for when verifying
* certificates, set this flags to true. It is false by
* default.
*/
public boolean ocspCheckingEnabled = false;
/**
* Specify the location and cert of the responder.
* If OCSP checking is enabled *and* this variable is
* set to some URL, all OCSP checking will be done via
* this URL.
*
* If this variable is null, the OCSP responder URL will
* be obtained from the AIA extension in the certificate
* being queried.
*
* If this is set, you must also set ocspResponderCertNickname
*
*/
public String ocspResponderURL = null;
/**
* The nickname of the cert to trust (expected) to
* sign the OCSP responses.
* Only checked when the OCSPResponder value is set.
*/
public String ocspResponderCertNickname = null;
/**
* Install the JSS crypto provider. Default is true.
*/
public boolean installJSSProvider = true;
/**
* Remove the Sun crypto provider. Default is false.
*/
public boolean removeSunProvider = false;
/**
* If true, none of the underlying NSS components will
* be initialized. Only the Java portions of JSS will be
* initialized. This should only be used if NSS has been initialized
* elsewhere.
*
*
Specifically, the following components will not be * configured by CryptoManager.initialize if this flag is set: *
The default is false. */ public boolean initializeJavaOnly = false; /** * Enable PKIX verify rather than the old cert library, * to verify certificates. Default is false. */ public boolean PKIXVerify = false; /** * Don't open the cert DB and key DB's, just * initialize the volatile certdb. Default is false. */ public boolean noCertDB = false; /** * Don't open the security module DB, * just initialize the PKCS #11 module. * Default is false. */ public boolean noModDB = false; /** * Continue to force initializations even if the * databases cannot be opened. * Default is false. */ public boolean forceOpen = false; /** * Don't try to look for the root certs module * automatically. * Default is false. */ public boolean noRootInit = false; /** * Use smaller tables and caches. * Default is false. */ public boolean optimizeSpace = false; /** * only load PKCS#11 modules that are * thread-safe, ie. that support locking - either OS * locking or NSS-provided locks . If a PKCS#11 * module isn't thread-safe, don't serialize its * calls; just don't load it instead. This is necessary * if another piece of code is using the same PKCS#11 * modules that NSS is accessing without going through * NSS, for example the Java SunPKCS11 provider. * Default is false. */ public boolean PK11ThreadSafe = false; /** * Init PK11Reload to ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED * error when loading PKCS#11 modules. This is necessary * if another piece of code is using the same PKCS#11 * modules that NSS is accessing without going through * NSS, for example Java SunPKCS11 provider. * default is false. */ public boolean PK11Reload = false; /** * never call C_Finalize on any * PKCS#11 module. This may be necessary in order to * ensure continuous operation and proper shutdown * sequence if another piece of code is using the same * PKCS#11 modules that NSS is accessing without going * through NSS, for example Java SunPKCS11 provider. * The following limitation applies when this is set : * SECMOD_WaitForAnyTokenEvent will not use * C_WaitForSlotEvent, in order to prevent the need for * C_Finalize. This call will be emulated instead. * Default is false. */ public boolean noPK11Finalize = false; /** * Sets 4 recommended options for applications that * use both NSS and the Java SunPKCS11 provider. * Default is false. */ public boolean cooperate = false; } //////////////////////////////////////////////////// // Module and Token Management //////////////////////////////////////////////////// /** * Retrieves the internal cryptographic services token. This is the * token built into NSS that performs bulk * cryptographic operations. *
In FIPS mode, the internal cryptographic services token is the * same as the internal key storage token. * * @return The internal cryptographic services token. */ public synchronized CryptoToken getInternalCryptoToken() { return internalCryptoToken; } /** * Retrieves the internal key storage token. This is the token * provided by NSS to store private keys. * The keys stored in this token are stored in an encrypted key database. *
In FIPS mode, the internal key storage token is the same as
* the internal cryptographic services token.
*
* @return The internal key storage token.
*/
public synchronized CryptoToken getInternalKeyStorageToken() {
return internalKeyStorageToken;
}
/**
* Looks up the CryptoToken with the given name. Searches all
* loaded cryptographic modules for the token.
*
* @param name The name of the token.
* @exception org.mozilla.jss.NoSuchTokenException If no token
* is found with the given name.
*/
public synchronized CryptoToken getTokenByName(String name)
throws NoSuchTokenException
{
Enumeration tokens = getAllTokens();
CryptoToken token;
while(tokens.hasMoreElements()) {
token = (CryptoToken) tokens.nextElement();
try {
if( name.equals(token.getName()) ) {
return token;
}
} catch( TokenException e ) {
Assert._assert(false, "Got a token exception");
}
}
throw new NoSuchTokenException();
}
/**
* Retrieves all tokens that support the given algorithm.
*
*/
public synchronized Enumeration getTokensSupportingAlgorithm(Algorithm alg)
{
Enumeration tokens = getAllTokens();
Vector goodTokens = new Vector();
CryptoToken tok;
while(tokens.hasMoreElements()) {
tok = (CryptoToken) tokens.nextElement();
if( tok.doesAlgorithm(alg) ) {
goodTokens.addElement(tok);
}
}
return goodTokens.elements();
}
/**
* Retrieves all tokens. This is an enumeration of all tokens on all
* modules.
*
* @return All tokens accessible from JSS. Each item of the enumeration
* is a CryptoToken
* @see org.mozilla.jss.crypto.CryptoToken
*/
public synchronized Enumeration getAllTokens() {
Enumeration modules = getModules();
Enumeration tokens;
Vector allTokens = new Vector();
while(modules.hasMoreElements()) {
tokens = ((PK11Module)modules.nextElement()).getTokens();
while(tokens.hasMoreElements()) {
allTokens.addElement( tokens.nextElement() );
}
}
return allTokens.elements();
}
/**
* Retrieves all tokens except those built into NSS.
* This excludes the internal token and the internal
* key storage token (which are one and the same in FIPS mode).
*
* @return All tokens accessible from JSS, except for the built-in
* internal tokens.
*/
public synchronized Enumeration getExternalTokens() {
Enumeration modules = getModules();
Enumeration tokens;
PK11Token token;
Vector allTokens = new Vector();
while(modules.hasMoreElements()) {
tokens = ((PK11Module)modules.nextElement()).getTokens();
while(tokens.hasMoreElements()) {
token = (PK11Token) tokens.nextElement();
if( ! token.isInternalCryptoToken() &&
! token.isInternalKeyStorageToken() )
{
allTokens.addElement( token );
}
}
}
return allTokens.elements();
}
/**
* Retrieves all installed cryptographic modules.
*
* @return An enumeration of all installed PKCS #11 modules. Each
* item in the enumeration is a PK11Module
.
* @see org.mozilla.jss.pkcs11.PK11Module
*/
public synchronized Enumeration getModules() {
return moduleVector.elements();
}
// Need to reload modules after adding new one
//public native addModule(String name, String libraryName);
/**
* The list of modules. This should be initialized by the constructor
* and updated whenever 1) a new module is added, 2) a module is deleted,
* or 3) FIPS mode is switched.
*/
private Vector moduleVector;
/**
* Re-creates the Vector of modules that is stored by CryptoManager.
* This entails going into native code to enumerate all modules,
* wrap each one in a PK11Module, and storing the PK11Module in the vector.
*/
private synchronized void reloadModules() {
moduleVector = new Vector();
putModulesInVector(moduleVector);
// Get the internal tokens
Enumeration tokens = getAllTokens();
internalCryptoToken = null;
internalKeyStorageToken = null;
while(tokens.hasMoreElements()) {
PK11Token token = (PK11Token) tokens.nextElement();
if( token.isInternalCryptoToken() ) {
Assert._assert(internalCryptoToken == null);
internalCryptoToken = token;
}
if( token.isInternalKeyStorageToken() ) {
Assert._assert(internalKeyStorageToken == null);
internalKeyStorageToken = token;
}
}
Assert._assert(internalKeyStorageToken != null);
Assert._assert(internalCryptoToken != null);
}
/**
* The internal cryptographic services token.
*/
private CryptoToken internalCryptoToken;
/**
* The internal key storage token.
*/
private CryptoToken internalKeyStorageToken;
/**
* Native code to traverse all PKCS #11 modules, wrap each one in
* a PK11Module, and insert each PK11Module into the given vector.
*/
private native void putModulesInVector(Vector vector);
///////////////////////////////////////////////////////////////////////
// Constructor and Accessors
///////////////////////////////////////////////////////////////////////
/**
* Constructor, for internal use only.
*/
protected CryptoManager() {
TokenSupplierManager.setTokenSupplier(this);
reloadModules();
}
/**
* Retrieve the single instance of CryptoManager.
* This cannot be called before initialization.
*
* @see #initialize(CryptoManager.InitializationValues)
* @exception NotInitializedException If
* initialize(InitializationValues
has not yet been
* called.
*/
public synchronized static CryptoManager getInstance()
throws NotInitializedException
{
if(instance==null) {
throw new NotInitializedException();
}
return instance;
}
/**
* The singleton instance, and a static initializer to create it.
*/
private static CryptoManager instance=null;
///////////////////////////////////////////////////////////////////////
// FIPS management
///////////////////////////////////////////////////////////////////////
/**
* Enables or disables FIPS-140-2 compliant mode. If this returns true,
* you must reloadModules(). This should only be called once in a program,
* at the beginning, because it invalidates tokens and modules.
*
* @param fips true to turn FIPS compliant mode on, false to turn it off.
*/
private static native boolean enableFIPS(boolean fips)
throws GeneralSecurityException;
/**
* Determines whether FIPS-140-2 compliance is active.
*
* @return true if the security library is in FIPS-140-2 compliant mode.
*/
public synchronized native boolean FIPSEnabled();
///////////////////////////////////////////////////////////////////////
// Password Callback management
///////////////////////////////////////////////////////////////////////
/**
* This function sets the global password callback. It is
* not thread-safe to change this.
*
The callback may be NULL, in which case password callbacks will
* fail gracefully.
*/
public synchronized void setPasswordCallback(PasswordCallback pwcb) {
passwordCallback = pwcb;
setNativePasswordCallback( pwcb );
}
private native void setNativePasswordCallback(PasswordCallback cb);
/**
* Returns the currently registered password callback.
*/
public synchronized PasswordCallback getPasswordCallback() {
return passwordCallback;
}
private PasswordCallback passwordCallback;
////////////////////////////////////////////////////
// Initialization
////////////////////////////////////////////////////
/**
* Initialize the security subsystem. Opens the databases, loads all
* PKCS #11 modules, initializes the internal random number generator.
* The initialize
methods that take arguments should be
* called only once, otherwise they will throw
* an exception. It is OK to call them after calling
* initialize()
.
*
* @param configDir The directory containing the security databases.
* @exception org.mozilla.jss.KeyDatabaseException Unable to open
* the key database, or it was currupted.
* @exception org.mozilla.jss.CertDatabaseException Unable
* to open the certificate database, or it was currupted.
**/
public static synchronized void initialize( String configDir )
throws KeyDatabaseException,
CertDatabaseException,
AlreadyInitializedException,
GeneralSecurityException
{
initialize( new InitializationValues(configDir) );
}
/**
* Initialize the security subsystem. Opens the databases, loads all
* PKCS #11 modules, initializes the internal random number generator.
* The initialize
methods that take arguments should be
* called only once, otherwise they will throw
* an exception. It is OK to call them after calling
* initialize()
.
*
* @param values The options with which to initialize CryptoManager.
* @exception org.mozilla.jss.KeyDatabaseException Unable to open
* the key database, or it was corrupted.
* @exception org.mozilla.jss.CertDatabaseException Unable
* to open the certificate database, or it was currupted.
**/
public static synchronized void initialize( InitializationValues values )
throws
KeyDatabaseException,
CertDatabaseException,
AlreadyInitializedException,
GeneralSecurityException
{
if(instance != null) {
throw new AlreadyInitializedException();
}
loadNativeLibraries();
if (values.ocspResponderURL != null) {
if (values.ocspResponderCertNickname == null) {
throw new GeneralSecurityException(
"Must set ocspResponderCertNickname");
}
}
initializeAllNative2(values.configDir,
values.certPrefix,
values.keyPrefix,
values.secmodName,
values.readOnly,
values.getManufacturerID(),
values.getLibraryDescription(),
values.getInternalTokenDescription(),
values.getInternalKeyStorageTokenDescription(),
values.getInternalSlotDescription(),
values.getInternalKeyStorageSlotDescription(),
values.getFIPSSlotDescription(),
values.getFIPSKeyStorageSlotDescription(),
values.ocspCheckingEnabled,
values.ocspResponderURL,
values.ocspResponderCertNickname,
values.initializeJavaOnly,
values.PKIXVerify,
values.noCertDB,
values.noModDB,
values.forceOpen,
values.noRootInit,
values.optimizeSpace,
values.PK11ThreadSafe,
values.PK11Reload,
values.noPK11Finalize,
values.cooperate
);
instance = new CryptoManager();
instance.setPasswordCallback(values.passwordCallback);
if( values.fipsMode != InitializationValues.FIPSMode.UNCHANGED) {
if( enableFIPS(values.fipsMode ==
InitializationValues.FIPSMode.ENABLED) )
{
instance.reloadModules();
}
}
// Force class load before we install the provider. Otherwise we get
// an infinite loop as the Security manager tries to instantiate the
// digest to verify its own JAR file.
JSSMessageDigestSpi mds = new JSSMessageDigestSpi.SHA1();
// Force the KeyType class to load before we can install JSS as a
// provider. JSS's signature provider accesses KeyType.
KeyType kt = KeyType.getKeyTypeFromAlgorithm(
SignatureAlgorithm.RSASignatureWithSHA1Digest);
if( values.installJSSProvider ) {
int position = java.security.Security.insertProviderAt(
new JSSProvider(), 1);
// This returns -1 if the provider was already installed, in which
// case it is not installed again. Is this
// an error? I don't think so, although it might be confusing
// if the provider is not in the position they expected.
// However, this will only happen if they are installing the
// provider themselves, so presumably they know what they're
// doing.
}
if( values.removeSunProvider ) {
java.security.Security.removeProvider("SUN");
}
}
private static native void
initializeAllNative2(String configDir,
String certPrefix,
String keyPrefix,
String secmodName,
boolean readOnly,
String manufacturerID,
String libraryDescription,
String internalTokenDescription,
String internalKeyStorageTokenDescription,
String internalSlotDescription,
String internalKeyStorageSlotDescription,
String fipsSlotDescription,
String fipsKeyStorageSlotDescription,
boolean ocspCheckingEnabled,
String ocspResponderURL,
String ocspResponderCertNickname,
boolean initializeJavaOnly,
boolean PKIXVerify,
boolean noCertDB,
boolean noModDB,
boolean forceOpen,
boolean noRootInit,
boolean optimizeSpace,
boolean PK11ThreadSafe,
boolean PK11Reload,
boolean noPK11Finalize,
boolean cooperate)
throws KeyDatabaseException,
CertDatabaseException,
AlreadyInitializedException;
/////////////////////////////////////////////////////////////
// Cert Lookup
/////////////////////////////////////////////////////////////
/**
* Retrieves all CA certificates in the trust database. This
* is a fairly expensive operation in that it involves traversing
* the entire certificate database.
* @return An array of all CA certificates stored permanently
* in the trust database.
*/
public native X509Certificate[]
getCACerts();
/**
* Retrieves all certificates in the trust database. This
* is a fairly expensive operation in that it involves traversing
* the entire certificate database.
* @return An array of all certificates stored permanently
* in the trust database.
*/
public native X509Certificate[]
getPermCerts();
/**
* Imports a chain of certificates. The leaf certificate may be a
* a user certificate, that is, a certificate that belongs to the
* current user and whose private key is available for use.
* If the leaf certificate is a user certificate, it is stored
* on the token
* that contains the corresponding private key, and is assigned the
* given nickname.
*
* @param certPackage An encoded certificate or certificate chain.
* Acceptable
* encodings are binary PKCS #7 SignedData objects and
* DER-encoded certificates, which may or may not be wrapped
* in a Base-64 encoding package surrounded by
* "-----BEGIN CERTIFICATE-----
" and
* "-----END CERTIFICATE-----
".
* @param nickname The nickname for the user certificate. It must
* be unique. It is ignored if there is no user certificate.
* @return The leaf certificate from the chain.
* @exception CertificateEncodingException If the package encoding
* was not recognized.
* @exception NicknameConflictException If the leaf certificate
* is a user certificate, and another certificate already has the
* given nickname.
* @exception UserCertConflictException If the leaf certificate
* is a user certificate, but it has already been imported.
* @exception NoSuchItemOnTokenException If the leaf certificate is
* a user certificate, but the matching private key cannot be found.
* @exception TokenException If an error occurs importing a leaf
* certificate into a token.
*/
public X509Certificate
importCertPackage(byte[] certPackage, String nickname )
throws CertificateEncodingException,
NicknameConflictException,
UserCertConflictException,
NoSuchItemOnTokenException,
TokenException
{
return importCertPackageNative(certPackage, nickname, false, false);
}
/**
* Imports a chain of certificates. The leaf of the chain is a CA
* certificate AND a user certificate (this would only be called by
* a CA installing its own certificate).
*
* @param certPackage An encoded certificate or certificate chain.
* Acceptable
* encodings are binary PKCS #7 SignedData objects and
* DER-encoded certificates, which may or may not be wrapped
* in a Base-64 encoding package surrounded by
* "-----BEGIN CERTIFICATE-----
" and
* "-----END CERTIFICATE-----
".
* @param nickname The nickname for the user certificate. It must
* be unique.
* @return The leaf certificate from the chain.
* @exception CertificateEncodingException If the package encoding
* was not recognized.
* @exception NicknameConflictException If the leaf certificate
* another certificate already has the given nickname.
* @exception UserCertConflictException If the leaf certificate
* has already been imported.
* @exception NoSuchItemOnTokenException If the the private key matching
* the leaf certificate cannot be found.
* @exception TokenException If an error occurs importing the leaf
* certificate into a token.
*/
public X509Certificate
importUserCACertPackage(byte[] certPackage, String nickname)
throws CertificateEncodingException,
NicknameConflictException,
UserCertConflictException,
NoSuchItemOnTokenException,
TokenException
{
return importCertPackageNative(certPackage, nickname, false, true);
}
/**
* Imports a chain of certificates, none of which is a user certificate.
*
* @param certPackage An encoded certificate or certificate chain.
* Acceptable
* encodings are binary PKCS #7 SignedData objects and
* DER-encoded certificates, which may or may not be wrapped
* in a Base-64 encoding package surrounded by
* "-----BEGIN CERTIFICATE-----
" and
* "-----END CERTIFICATE-----
".
* @return The leaf certificate from the chain.
* @exception CertificateEncodingException If the package encoding
* was not recognized.
* @exception TokenException If an error occurs importing a leaf
* certificate into a token.
*/
public X509Certificate
importCACertPackage(byte[] certPackage)
throws CertificateEncodingException,
TokenException
{
try {
return importCertPackageNative(certPackage, null, true, false);
} catch(NicknameConflictException e) {
Assert.notReached("importing CA certs caused nickname conflict");
Debug.trace(Debug.ERROR,
"importing CA certs caused nickname conflict");
} catch(UserCertConflictException e) {
Assert.notReached("importing CA certs caused user cert conflict");
Debug.trace(Debug.ERROR,
"importing CA certs caused user cert conflict");
} catch(NoSuchItemOnTokenException e) {
Assert.notReached("importing CA certs caused NoSuchItemOnToken"+
"Exception");
Debug.trace(Debug.ERROR,
"importing CA certs caused NoSuchItemOnTokenException");
}
return null;
}
/**
* Imports a single certificate into the permanent certificate
* database.
*
* @param cert the certificate you want to add
* @param nickname the nickname you want to refer to the certificate as
* (must not be null)
*/
public InternalCertificate
importCertToPerm(X509Certificate cert, String nickname)
throws TokenException, InvalidNicknameException
{
if (nickname==null) {
throw new InvalidNicknameException("Nickname must be non-null");
}
else {
return importCertToPermNative(cert,nickname);
}
}
private native InternalCertificate
importCertToPermNative(X509Certificate cert, String nickname)
throws TokenException;
/**
* @param noUser true if we know that none of the certs are user certs.
* In this case, no attempt will be made to find a matching private
* key for the leaf certificate.
*/
private native X509Certificate
importCertPackageNative(byte[] certPackage, String nickname,
boolean noUser, boolean leafIsCA)
throws CertificateEncodingException,
NicknameConflictException,
UserCertConflictException,
NoSuchItemOnTokenException,
TokenException;
/*============ CRL importing stuff ********************************/
private static int TYPE_KRL = 0;
private static int TYPE_CRL = 1;
/**
* Imports a CRL, and stores it into the cert7.db
* Validate CRL then import it to the dbase. If there is already a CRL with the
* same CA in the dbase, it will be replaced if derCRL is more up to date.
*
* @param crl the DER-encoded CRL.
* @param url the URL where this CRL can be retrieved from (for future updates).
* [ note that CRLs are not retrieved automatically ]. Can be null
* @exception CRLImportException If the package encoding
* was not recognized.
*/
public void
importCRL(byte[] crl,String url)
throws CRLImportException,
TokenException
{
importCRLNative(crl,url,TYPE_CRL);
}
/**
* Imports a CRL, and stores it into the cert7.db
*
* @param the DER-encoded CRL.
*/
private native
void importCRLNative(byte[] crl, String url, int rl_type)
throws CRLImportException, TokenException;
/*============ Cert Exporting stuff ********************************/
/**
* Exports one or more certificates into a PKCS #7 certificate container.
* This is just a SignedData object whose certificates
* field contains the given certificates but whose content field
* is empty.
*
* @param certs One or more certificates that should be exported into
* the PKCS #7 object. The leaf certificate should be the first
* in the chain. The output of buildCertificateChain
* would be appropriate here.
* @exception CertificateEncodingException If the array is empty,
* or an error occurred encoding the certificates.
* @return A byte array containing a PKCS #7 SignedData object.
* @see #buildCertificateChain
*/
public native byte[]
exportCertsToPKCS7(X509Certificate[] certs)
throws CertificateEncodingException;
/**
* Looks up a certificate given its nickname.
*
* @param nickname The nickname of the certificate to look for.
* @return The certificate matching this nickname, if one is found.
* @exception ObjectNotFoundException If no certificate could be found
* with the given nickname.
* @exception TokenException If an error occurs in the security library.
*/
public org.mozilla.jss.crypto.X509Certificate
findCertByNickname(String nickname)
throws ObjectNotFoundException, TokenException
{
Assert._assert(nickname!=null);
return findCertByNicknameNative(nickname);
}
/**
* Returns all certificates with the given nickname.
*
* @param nickname The nickname of the certificate to look for.
* @return The certificates matching this nickname. The array may be empty
* if no matching certs were found.
* @exception TokenException If an error occurs in the security library.
*/
public org.mozilla.jss.crypto.X509Certificate[]
findCertsByNickname(String nickname)
throws TokenException
{
Assert._assert(nickname!=null);
return findCertsByNicknameNative(nickname);
}
/**
* Looks up a certificate by issuer and serial number. The internal
* database and all PKCS #11 modules are searched.
*
* @param derIssuer The DER encoding of the certificate issuer name.
* The issuer name has ASN.1 type Name, which is defined in
* X.501.
* @param serialNumber The certificate serial number.
* @exception ObjectNotFoundException If the certificate is not found
* in the internal certificate database or on any PKCS #11 token.
* @exception TokenException If an error occurs in the security library.
*/
public org.mozilla.jss.crypto.X509Certificate
findCertByIssuerAndSerialNumber(byte[] derIssuer, INTEGER serialNumber)
throws ObjectNotFoundException, TokenException
{
try {
ANY sn = (ANY) ASN1Util.decode(ANY.getTemplate(),
ASN1Util.encode(serialNumber) );
return findCertByIssuerAndSerialNumberNative(derIssuer,
sn.getContents() );
} catch( InvalidBERException e ) {
Assert.notReached("Invalid BER encoding of INTEGER");
return null;
}
}
/**
* @param serialNumber The contents octets of a DER-encoding of the
* certificate serial number.
*/
private native org.mozilla.jss.crypto.X509Certificate
findCertByIssuerAndSerialNumberNative(byte[] derIssuer, byte[] serialNumber)
throws ObjectNotFoundException, TokenException;
protected native org.mozilla.jss.crypto.X509Certificate
findCertByNicknameNative(String nickname)
throws ObjectNotFoundException, TokenException;
protected native org.mozilla.jss.crypto.X509Certificate[]
findCertsByNicknameNative(String nickname)
throws TokenException;
/////////////////////////////////////////////////////////////
// build cert chains
/////////////////////////////////////////////////////////////
/**
* Given a certificate, constructs its certificate chain. It may
* or may not chain up to a trusted root.
* @param leaf The certificate that is the starting point of the chain.
* @return An array of certificates, starting at the leaf and ending
* with the highest certificate on the chain that was found.
* @throws CertificateException If the certificate is not recognized
* by the underlying provider.
*/
public org.mozilla.jss.crypto.X509Certificate[]
buildCertificateChain(org.mozilla.jss.crypto.X509Certificate leaf)
throws java.security.cert.CertificateException, TokenException
{
if( ! (leaf instanceof PK11Cert) ) {
throw new CertificateException(
"Certificate is not a PKCS #11 certificate");
}
return buildCertificateChainNative((PK11Cert)leaf);
}
native org.mozilla.jss.crypto.X509Certificate[]
buildCertificateChainNative(PK11Cert leaf)
throws CertificateException, TokenException;
/////////////////////////////////////////////////////////////
// lookup private keys
/////////////////////////////////////////////////////////////
/**
* Looks up the PrivateKey matching the given certificate.
*
* @exception ObjectNotFoundException If no private key can be
* found matching the given certificate.
* @exception TokenException If an error occurs in the security library.
*/
public org.mozilla.jss.crypto.PrivateKey
findPrivKeyByCert(org.mozilla.jss.crypto.X509Certificate cert)
throws ObjectNotFoundException, TokenException
{
Assert._assert(cert!=null);
if(! (cert instanceof org.mozilla.jss.pkcs11.PK11Cert)) {
Assert.notReached("non-pkcs11 cert passed to PK11Finder");
throw new ObjectNotFoundException();
}
return findPrivKeyByCertNative(cert);
}
protected native org.mozilla.jss.crypto.PrivateKey
findPrivKeyByCertNative(org.mozilla.jss.crypto.X509Certificate cert)
throws ObjectNotFoundException, TokenException;
/////////////////////////////////////////////////////////////
// Provide Pseudo-Random Number Generation
/////////////////////////////////////////////////////////////
/**
* Retrieves a FIPS-140-2 validated random number generator.
*
* @return A JSS SecureRandom implemented with FIPS-validated NSS.
*/
public org.mozilla.jss.crypto.JSSSecureRandom
createPseudoRandomNumberGenerator()
{
return new PK11SecureRandom();
}
/**
* Retrieves a FIPS-140-2 validated random number generator.
*
* @return A JSS SecureRandom implemented with FIPS-validated NSS.
*/
public org.mozilla.jss.crypto.JSSSecureRandom
getSecureRNG() {
return new PK11SecureRandom();
}
/********************************************************************/
/* The VERSION Strings should be updated in the following */
/* files everytime a new release of JSS is generated: */
/* */
/* lib/manifest.mn */
/* org/mozilla/jss/CryptoManager.c */
/* org/mozilla/jss/CryptoManager.java */
/* org/mozilla/jss/JSSProvider.java */
/* org/mozilla/jss/util/jssver.h */
/* */
/********************************************************************/
public static final String
JAR_JSS_VERSION = "JSS_VERSION = JSS_4_4_0_RTM";
public static final String
JAR_JDK_VERSION = "JDK_VERSION = N/A";
public static final String
JAR_NSS_VERSION = "NSS_VERSION = N/A";
public static final String
JAR_DBM_VERSION = "DBM_VERSION = N/A";
public static final String
JAR_NSPR_VERSION = "NSPR_VERSION = N/A";
/**
* Loads the JSS dynamic library if necessary.
*
This method is idempotent. */ synchronized static void loadNativeLibraries() { if( ! mNativeLibrariesLoaded ) { try { // 64 bit rhel/fedora System.load( "/usr/lib64/jss/libjss4.so" ); Debug.trace(Debug.VERBOSE, "64-bit jss library loaded"); mNativeLibrariesLoaded = true; } catch( UnsatisfiedLinkError e ) { try { // 32 bit rhel/fedora System.load( "/usr/lib/jss/libjss4.so" ); Debug.trace(Debug.VERBOSE, "32-bit jss library loaded"); mNativeLibrariesLoaded = true; } catch( UnsatisfiedLinkError f ) { try {// possibly other platforms System.loadLibrary( "jss4" ); Debug.trace(Debug.VERBOSE, "jss library loaded"); mNativeLibrariesLoaded = true; } catch( UnsatisfiedLinkError g ) { Debug.trace(Debug.VERBOSE, "jss library load failed"); } } } } } static private boolean mNativeLibrariesLoaded = false; // Hashtable is synchronized. private Hashtable perThreadTokenTable = new Hashtable(); /** * Sets the default token for the current thread. This token will * be used when JSS is called through the JCA interface, which has * no means of specifying which token to use. * *
If no token is set, the InternalKeyStorageToken will be used. Setting * this thread's token to null will also cause the * InternalKeyStorageToken to be used. * * @param token The token to use for crypto operations. Specifying * null will cause the InternalKeyStorageToken to be used. */ public void setThreadToken(CryptoToken token) { if( token != null ) { perThreadTokenTable.put(Thread.currentThread(), token); } else { perThreadTokenTable.remove(Thread.currentThread()); } } /** * Returns the default token for the current thread. This token will * be used when JSS is called through the JCA interface, which has * no means of specifying which token to use. * *
If no token is set, the InternalKeyStorageToken will be used. Setting
* this thread's token to null will also cause the
* InternalKeyStorageToken to be used.
*
* @return The default token for this thread. If it has not been specified,
* it will be the InternalKeyStorageToken.
*/
public CryptoToken getThreadToken() {
CryptoToken tok =
(CryptoToken) perThreadTokenTable.get(Thread.currentThread());
if( tok == null ) {
tok = getInternalKeyStorageToken();
}
return tok;
}
/////////////////////////////////////////////////////////////
// isCertValid
/////////////////////////////////////////////////////////////
/**
* Verify a certificate that exists in the given cert database,
* check if is valid and that we trust the issuer. Verify time
* against Now.
* @param nickname The nickname of the certificate to verify.
* @param checkSig verify the signature of the certificate
* @return currCertificateUsage which contains current usage bit map as defined in CertificateUsage
*
* @exception InvalidNicknameException If the nickname is null
* @exception ObjectNotFoundException If no certificate could be found
* with the given nickname.
*/
public int isCertValid(String nickname, boolean checkSig)
throws ObjectNotFoundException, InvalidNicknameException
{
if (nickname==null) {
throw new InvalidNicknameException("Nickname must be non-null");
}
int currCertificateUsage = 0x0000; // initialize it to 0
currCertificateUsage = verifyCertificateNowCUNative(nickname,
checkSig);
return currCertificateUsage;
}
private native int verifyCertificateNowCUNative(String nickname,
boolean checkSig) throws ObjectNotFoundException;
/////////////////////////////////////////////////////////////
// isCertValid
/////////////////////////////////////////////////////////////
/**
* Verify a certificate that exists in the given cert database,
* check if is valid and that we trust the issuer. Verify time
* against Now.
* @param nickname The nickname of the certificate to verify.
* @param checkSig verify the signature of the certificate
* @param certificateUsage see certificateUsage defined to verify Certificate; to retrieve current certificate usage, call the isCertValid() above
* @return true for success; false otherwise
*
* @exception InvalidNicknameException If the nickname is null
* @exception ObjectNotFoundException If no certificate could be found
* with the given nickname.
* @deprecated Use verifyCertificate() instead
*/
public boolean isCertValid(String nickname, boolean checkSig,
CertificateUsage certificateUsage)
throws ObjectNotFoundException, InvalidNicknameException
{
if (nickname==null) {
throw new InvalidNicknameException("Nickname must be non-null");
}
// 0 certificate usage will get current usage
// should call isCertValid() call above that returns certificate usage
if ((certificateUsage == null) ||
(certificateUsage == CertificateUsage.CheckAllUsages)){
int currCertificateUsage = 0x0000;
currCertificateUsage = verifyCertificateNowCUNative(nickname,
checkSig);
if (currCertificateUsage == CertificateUsage.basicCertificateUsages){
// cert is good for nothing
return false;
} else
return true;
} else {
return verifyCertificateNowNative(nickname, checkSig,
certificateUsage.getUsage());
}
}
/**
* Verify a certificate that exists in the given cert database,
* check if it's valid and that we trust the issuer. Verify time
* against now.
* @param nickname nickname of the certificate to verify.
* @param checkSig verify the signature of the certificate
* @param certificateUsage see certificate usage defined to verify certificate
*
* @exception InvalidNicknameException If the nickname is null.
* @exception ObjectNotFoundException If no certificate could be found
* with the given nickname.
* @exception CertificateException If certificate is invalid.
*/
public void verifyCertificate(String nickname,
boolean checkSig,
CertificateUsage certificateUsage)
throws ObjectNotFoundException, InvalidNicknameException, CertificateException {
int usage = certificateUsage == null ? 0 : certificateUsage.getUsage();
verifyCertificateNowNative2(nickname, checkSig, usage);
}
private native boolean verifyCertificateNowNative(String nickname,
boolean checkSig, int certificateUsage) throws ObjectNotFoundException;
private native void verifyCertificateNowNative2(
String nickname,
boolean checkSig,
int certificateUsage)
throws ObjectNotFoundException, InvalidNicknameException, CertificateException;
/**
* note: this method calls obsolete function in NSS
*
* Verify a certificate that exists in the given cert database,
* check if is valid and that we trust the issuer. Verify time
* against Now.
* @param nickname The nickname of the certificate to verify.
* @param checkSig verify the signature of the certificate
* @param certUsage see exposed certUsage defines to verify Certificate
* @return true for success; false otherwise
*
* @exception InvalidNicknameException If the nickname is null
* @exception ObjectNotFoundException If no certificate could be found
* with the given nickname.
*/
public boolean isCertValid(String nickname, boolean checkSig,
CertUsage certUsage)
throws ObjectNotFoundException, InvalidNicknameException
{
if (nickname==null) {
throw new InvalidNicknameException("Nickname must be non-null");
}
return verifyCertNowNative(nickname, checkSig, certUsage.getUsage());
}
/*
* Obsolete in NSS
*/
private native boolean verifyCertNowNative(String nickname,
boolean checkSig, int cUsage) throws ObjectNotFoundException;
/////////////////////////////////////////////////////////////
// isCertValid
/////////////////////////////////////////////////////////////
/**
* Verify a certificate in memory. Check if
* valid and that we trust the issuer. Verify time
* against Now.
* @param certPackage certificate in memory
* @param checkSig verify the signature of the certificate
* @param certUsage see exposed certUsage defines to verify Certificate
* @return true for success; false otherwise
*
* @exception TokenException unable to insert temporary certificate
* into database.
* @exception CertificateEncodingException If the package encoding
* was not recognized.
*/
public boolean isCertValid(byte[] certPackage, boolean checkSig,
CertUsage certUsage)
throws TokenException, CertificateEncodingException
{
return verifyCertTempNative(certPackage , checkSig,
certUsage.getUsage());
}
private native boolean verifyCertTempNative(byte[] certPackage,
boolean checkSig, int cUsage)
throws TokenException, CertificateEncodingException;
///////////////////////////////////////////////////////////////////////
// OCSP management
///////////////////////////////////////////////////////////////////////
/**
* Enables OCSP, note when you Initialize JSS for the first time, for
* backwards compatibility, the initialize will enable OCSP if you
* previously set values.ocspCheckingEnabled and
* values.ocspResponderURL/values.ocspResponderCertNickname
* configureOCSP will allow changing of the the OCSPResponder at runtime.
* * @param ocspChecking true or false to enable/disable OCSP
* * @param ocspResponderURL - url of the OCSP responder
* * @param ocspResponderCertNickname - the nickname of the OCSP
* signer certificate or the CA certificate found in the cert DB
*/
public void configureOCSP(
boolean ocspCheckingEnabled,
String ocspResponderURL,
String ocspResponderCertNickname )
throws GeneralSecurityException
{
configureOCSPNative(ocspCheckingEnabled,
ocspResponderURL,
ocspResponderCertNickname );
}
private native void configureOCSPNative( boolean ocspCheckingEnabled,
String ocspResponderURL,
String ocspResponderCertNickname )
throws GeneralSecurityException;
/**
* change OCSP cache settings
* * @param ocsp_cache_size max cache entries
* * @param ocsp_min_cache_entry_duration minimum seconds to next fetch attempt
* * @param ocsp_max_cache_entry_duration maximum seconds to next fetch attempt
*/
public void OCSPCacheSettings(
int ocsp_cache_size,
int ocsp_min_cache_entry_duration,
int ocsp_max_cache_entry_duration)
throws GeneralSecurityException
{
OCSPCacheSettingsNative(ocsp_cache_size,
ocsp_min_cache_entry_duration,
ocsp_max_cache_entry_duration);
}
private native void OCSPCacheSettingsNative(
int ocsp_cache_size,
int ocsp_min_cache_entry_duration,
int ocsp_max_cache_entry_duration)
throws GeneralSecurityException;
/**
* set OCSP timeout value
* * @param ocspTimeout OCSP timeout in seconds
*/
public void setOCSPTimeout(
int ocsp_timeout )
throws GeneralSecurityException
{
setOCSPTimeoutNative( ocsp_timeout);
}
private native void setOCSPTimeoutNative(
int ocsp_timeout )
throws GeneralSecurityException;
}
jss-4.4.3/jss/org/mozilla/jss/DatabaseCloser.java 0000664 0000000 0000000 00000003023 13261450000 0021661 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss;
/**
* A class for closing databases. Since closing the databases is
* very dangerous and breaks the JSS model, it may only be done from
* special applications. This class should be subclasses by
* authorized subclasses. It cannot be instantiated itself.
*/
public abstract class DatabaseCloser {
private static final String authorizedClosers[] =
{ "org.mozilla.certsetup.apps.CertSetup$DatabaseCloser",
"org.mozilla.jss.CloseDBs" };
/**
* Creates a new DatabaseCloser. This should only be called
* from an authorized subclass. This class cannot itself be
* instantiated.
*
* @throws Exception If the instantiation is not a valid subclass.
*/
public DatabaseCloser() throws Exception {
Class clazz = this.getClass();
String name = clazz.getName();
boolean approved = false;
for(int i=0; i < authorizedClosers.length; i++) {
if( name.equals( authorizedClosers[i] ) ) {
approved = true;
break;
}
}
if(!approved) {
throw new Exception();
}
}
/**
* Closes the certificate and key databases. This is extremely
* dangerous.
*/
protected native void closeDatabases();
}
jss-4.4.3/jss/org/mozilla/jss/JSSProvider.java 0000664 0000000 0000000 00000031156 13261450000 0021167 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss;
public final class JSSProvider extends java.security.Provider {
/********************************************************************/
/* The VERSION Strings should be updated in the following */
/* files everytime a new release of JSS is generated: */
/* */
/* lib/manifest.mn */
/* org/mozilla/jss/CryptoManager.c */
/* org/mozilla/jss/CryptoManager.java */
/* org/mozilla/jss/JSSProvider.java */
/* org/mozilla/jss/util/jssver.h */
/* */
/********************************************************************/
/* QUESTION: When do we change MINOR and PATCH to 4 and 0? */
private static int JSS_MAJOR_VERSION = 4;
private static int JSS_MINOR_VERSION = 4;
private static int JSS_PATCH_VERSION = 0;
private static double JSS_VERSION = JSS_MAJOR_VERSION +
(JSS_MINOR_VERSION * 100 +
JSS_PATCH_VERSION)/10000.0;
public JSSProvider() {
super("Mozilla-JSS", JSS_VERSION,
"Provides Signature, Message Digesting, and RNG");
/////////////////////////////////////////////////////////////
// Signature
/////////////////////////////////////////////////////////////
put("Signature.SHA1withDSA",
"org.mozilla.jss.provider.java.security.JSSSignatureSpi$DSA");
put("Alg.Alias.Signature.DSA", "SHA1withDSA");
put("Alg.Alias.Signature.DSS", "SHA1withDSA");
put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA");
put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA");
put("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA");
put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA");
put("Signature.MD5/RSA",
"org.mozilla.jss.provider.java.security.JSSSignatureSpi$MD5RSA");
put("Alg.Alias.Signature.MD5withRSA", "MD5/RSA");
put("Signature.MD2/RSA",
"org.mozilla.jss.provider.java.security.JSSSignatureSpi$MD2RSA");
put("Signature.SHA-1/RSA",
"org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA1RSA");
put("Alg.Alias.Signature.SHA1/RSA", "SHA-1/RSA");
put("Alg.Alias.Signature.SHA1withRSA", "SHA-1/RSA");
put("Signature.SHA-256/RSA",
"org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA256RSA");
put("Alg.Alias.Signature.SHA256/RSA", "SHA-256/RSA");
put("Alg.Alias.Signature.SHA256withRSA", "SHA-256/RSA");
put("Signature.SHA-384/RSA",
"org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA384RSA");
put("Alg.Alias.Signature.SHA384/RSA", "SHA-384/RSA");
put("Alg.Alias.Signature.SHA384withRSA", "SHA-384/RSA");
put("Signature.SHA-512/RSA",
"org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA512RSA");
put("Alg.Alias.Signature.SHA512/RSA", "SHA-512/RSA");
put("Alg.Alias.Signature.SHA512withRSA", "SHA-512/RSA");
// ECC
put("Signature.SHA1withEC",
"org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA1EC");
put("Alg.Alias.Signature.EC", "SHA1withEC");
put("Alg.Alias.Signature.ECC", "SHA1withEC");
put("Alg.Alias.Signature.ECDSA", "SHA1withEC");
put("Alg.Alias.Signature.SHA/EC", "SHA1withEC");
put("Alg.Alias.Signature.SHA1/EC", "SHA1withEC");
put("Alg.Alias.Signature.SHA-1/EC", "SHA1withEC");
put("Alg.Alias.Signature.SHA/ECDSA", "SHA1withEC");
put("Alg.Alias.Signature.SHA1/ECDSA", "SHA1withEC");
put("Alg.Alias.Signature.SHA1withECDSA", "SHA1withEC"); //JCE Standard Name
put("Signature.SHA256withEC",
"org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA256EC");
put("Alg.Alias.Signature.SHA256/EC", "SHA256withEC");
put("Alg.Alias.Signature.SHA-256/EC", "SHA256withEC");
put("Alg.Alias.Signature.SHA256withECDSA", "SHA256withEC"); //JCE Standard Name
put("Signature.SHA384withEC",
"org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA384EC");
put("Alg.Alias.Signature.SHA384/EC", "SHA384withEC");
put("Alg.Alias.Signature.SHA-384/EC", "SHA384withEC");
put("Alg.Alias.Signature.SHA384withECDSA", "SHA384withEC"); //JCE Standard Name
put("Signature.SHA512withEC",
"org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA512EC");
put("Alg.Alias.Signature.SHA512/EC", "SHA512withEC");
put("Alg.Alias.Signature.SHA-512/EC", "SHA512withEC");
put("Alg.Alias.Signature.SHA512withECDSA", "SHA512withEC"); //JCE Standard Name
/////////////////////////////////////////////////////////////
// Message Digesting
/////////////////////////////////////////////////////////////
put("MessageDigest.SHA-1",
"org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$SHA1");
put("MessageDigest.MD2",
"org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$MD2");
put("MessageDigest.MD5",
"org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$MD5");
put("MessageDigest.SHA-256",
"org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$SHA256");
put("MessageDigest.SHA-384",
"org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$SHA384");
put("MessageDigest.SHA-512",
"org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$SHA512");
put("Alg.Alias.MessageDigest.SHA1", "SHA-1");
put("Alg.Alias.MessageDigest.SHA", "SHA-1");
put("Alg.Alias.MessageDigest.SHA256", "SHA-256");
put("Alg.Alias.MessageDigest.SHA384", "SHA-384");
put("Alg.Alias.MessageDigest.SHA512", "SHA-512");
/////////////////////////////////////////////////////////////
// SecureRandom
/////////////////////////////////////////////////////////////
put("SecureRandom.pkcs11prng",
"org.mozilla.jss.provider.java.security.JSSSecureRandomSpi");
/////////////////////////////////////////////////////////////
// KeyPairGenerator
/////////////////////////////////////////////////////////////
put("KeyPairGenerator.RSA",
"org.mozilla.jss.provider.java.security.JSSKeyPairGeneratorSpi$RSA");
put("KeyPairGenerator.DSA",
"org.mozilla.jss.provider.java.security.JSSKeyPairGeneratorSpi$DSA");
put("KeyPairGenerator.EC",
"org.mozilla.jss.provider.java.security.JSSKeyPairGeneratorSpi$EC");
/////////////////////////////////////////////////////////////
// KeyFactory
/////////////////////////////////////////////////////////////
put("KeyFactory.RSA",
"org.mozilla.jss.provider.java.security.KeyFactorySpi1_2");
put("KeyFactory.DSA",
"org.mozilla.jss.provider.java.security.KeyFactorySpi1_2");
put("KeyFactory.EC",
"org.mozilla.jss.provider.java.security.KeyFactorySpi1_2");
/////////////////////////////////////////////////////////////
// AlgorithmParameters
/////////////////////////////////////////////////////////////
put("AlgorithmParameters.IvAlgorithmParameters",
"org.mozilla.jss.provider.java.security.IvAlgorithmParameters");
put("AlgorithmParameters.RC2AlgorithmParameters",
"org.mozilla.jss.provider.java.security.RC2AlgorithmParameters");
/////////////////////////////////////////////////////////////
// Cipher
/////////////////////////////////////////////////////////////
put("Cipher.DES",
"org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$DES");
put("Cipher.DESede",
"org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$DESede");
put("Alg.Alias.Cipher.DES3", "DESede");
put("Cipher.AES",
"org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$AES");
put("Cipher.RC4",
"org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$RC4");
put("Cipher.RSA",
"org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$RSA");
put("Cipher.RC2",
"org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$RC2");
/////////////////////////////////////////////////////////////
// KeyGenerator
/////////////////////////////////////////////////////////////
put("KeyGenerator.DES",
"org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$DES");
put("KeyGenerator.DESede",
"org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$DESede");
put("Alg.Alias.KeyGenerator.DES3", "DESede");
put("KeyGenerator.AES",
"org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$AES");
put("KeyGenerator.RC4",
"org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$RC4");
put("KeyGenerator.RC2",
"org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$RC2");
put("KeyGenerator.HmacSHA1",
"org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$HmacSHA1");
put("KeyGenerator.PBAHmacSHA1",
"org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$PBAHmacSHA1");
/////////////////////////////////////////////////////////////
// SecretKeyFactory
/////////////////////////////////////////////////////////////
put("SecretKeyFactory.DES",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$DES");
put("SecretKeyFactory.DESede",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$DESede");
put("Alg.Alias.SecretKeyFactory.DES3", "DESede");
put("SecretKeyFactory.AES",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$AES");
put("SecretKeyFactory.RC4",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$RC4");
put("SecretKeyFactory.RC2",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$RC2");
put("SecretKeyFactory.HmacSHA1",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$HmacSHA1");
put("SecretKeyFactory.PBAHmacSHA1",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBAHmacSHA1");
put("SecretKeyFactory.PBEWithMD5AndDES",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBE_MD5_DES_CBC");
put("SecretKeyFactory.PBEWithSHA1AndDES",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBE_SHA1_DES_CBC");
put("SecretKeyFactory.PBEWithSHA1AndDESede",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBE_SHA1_DES3_CBC");
put("Alg.Alias.SecretKeyFactory.PBEWithSHA1AndDES3", "PBEWithSHA1AndDESede");
put("SecretKeyFactory.PBEWithSHA1And128RC4",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBE_SHA1_RC4_128");
/////////////////////////////////////////////////////////////
// MAC
/////////////////////////////////////////////////////////////
put("Mac.HmacSHA1",
"org.mozilla.jss.provider.javax.crypto.JSSMacSpi$HmacSHA1");
put("Alg.Alias.Mac.Hmac-SHA1", "HmacSHA1");
put("Mac.HmacSHA256",
"org.mozilla.jss.provider.javax.crypto.JSSMacSpi$HmacSHA256");
put("Alg.Alias.Mac.Hmac-SHA256", "HmacSHA256");
put("Mac.HmacSHA384",
"org.mozilla.jss.provider.javax.crypto.JSSMacSpi$HmacSHA384");
put("Alg.Alias.Mac.Hmac-SHA384", "HmacSHA384");
put("Mac.HmacSHA512",
"org.mozilla.jss.provider.javax.crypto.JSSMacSpi$HmacSHA512");
put("Alg.Alias.Mac.Hmac-SHA512", "HmacSHA512");
}
public String toString() {
String mozillaProviderVersion = JSS_MAJOR_VERSION + "." +
JSS_MINOR_VERSION;
if ( JSS_PATCH_VERSION != 0 ) {
mozillaProviderVersion = mozillaProviderVersion + "." +
JSS_PATCH_VERSION;
}
return "Mozilla-JSS version " + mozillaProviderVersion;
}
}
jss-4.4.3/jss/org/mozilla/jss/KeyDatabaseException.java 0000664 0000000 0000000 00000001013 13261450000 0023036 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss;
/**
* This exception is thrown if the key database does not exist, or if
* an error occurs while opening it.
*/
public class KeyDatabaseException extends java.lang.Exception {
public KeyDatabaseException() {}
public KeyDatabaseException(String mesg) {
super(mesg);
}
}
jss-4.4.3/jss/org/mozilla/jss/Makefile 0000664 0000000 0000000 00000003525 13261450000 0017611 0 ustar 00root root 0000000 0000000 #! gmake
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#######################################################################
# (1) Include initial platform-independent assignments (MANDATORY). #
#######################################################################
include manifest.mn
#######################################################################
# (2) Include "global" configuration information. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
# (3) Include "component" configuration information. (OPTIONAL) #
#######################################################################
#######################################################################
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
#######################################################################
include config.mk
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/rules.mk
#######################################################################
# (6) Execute "component" rules. (OPTIONAL) #
#######################################################################
#######################################################################
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################
include rules.mk
jss-4.4.3/jss/org/mozilla/jss/NoSuchTokenException.java 0000664 0000000 0000000 00000000706 13261450000 0023071 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss;
/**
* Thrown if a token cannot be found.
*/
public class NoSuchTokenException extends java.lang.Exception {
public NoSuchTokenException() {}
public NoSuchTokenException(String mesg) {
super(mesg);
}
}
jss-4.4.3/jss/org/mozilla/jss/PK11Finder.c 0000664 0000000 0000000 00000160151 13261450000 0020120 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "_jni/org_mozilla_jss_CryptoManager.h"
#include KeyManager is used to create, lookup, and delete the symmetric keys used
for SecretDecoderRing. Encryptor is used to encrypt data. Decryptor is used
to decrypt data that was previously encrypted with Encryptor. Encoding
and Encoding.Template are used internally, but they were made public
because they may occasionally be useful to applications.
jss-4.4.3/jss/org/mozilla/jss/asn1/ 0000775 0000000 0000000 00000000000 13261450000 0017006 5 ustar 00root root 0000000 0000000 jss-4.4.3/jss/org/mozilla/jss/asn1/ANY.java 0000664 0000000 0000000 00000020407 13261450000 0020303 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import org.mozilla.jss.util.Assert;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
/**
* Represents an ASN.1 An If null is passed in, this method will return true
* if this algorithm takes no parameters, and false
* if this algorithm does take parameters.
*/
public boolean isValidParameterObject(Object o) {
if( o == null ) {
return (parameterClasses.length == 0);
}
if( parameterClasses.length == 0 ){
return false;
}
Class c = o.getClass();
for( int i = 0; i < parameterClasses.length; ++i) {
if( c.equals( parameterClasses[i] ) ) {
return true;
}
}
return false;
}
/**
* Index into the SECOidTag array in Algorithm.c.
*/
protected int oidIndex;
String name;
protected OBJECT_IDENTIFIER oid;
private Class[] parameterClasses=new Class[0];
//////////////////////////////////////////////////////////////
// Algorithm OIDs
//////////////////////////////////////////////////////////////
static final OBJECT_IDENTIFIER ANSI_X9_ALGORITHM =
new OBJECT_IDENTIFIER( new long[] { 1, 2, 840, 10040, 4 } );
static final OBJECT_IDENTIFIER ANSI_X962_OID =
new OBJECT_IDENTIFIER( new long[] { 1, 2, 840, 10045 } );
// Algorithm indices. These must be kept in sync with the
// algorithm array in Algorithm.c.
protected static final short SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION=0;
protected static final short SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION=1;
protected static final short SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION=2;
protected static final short SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST=3;
protected static final short SEC_OID_PKCS1_RSA_ENCRYPTION=4;
protected static final short CKM_RSA_PKCS_KEY_PAIR_GEN=5;
protected static final short CKM_DSA_KEY_PAIR_GEN=6;
protected static final short SEC_OID_ANSIX9_DSA_SIGNATURE=7;
protected static final short SEC_OID_RC4=8;
protected static final short SEC_OID_DES_ECB=9;
protected static final short SEC_OID_DES_CBC=10;
protected static final short CKM_DES_CBC_PAD=11;
protected static final short CKM_DES3_ECB=12;
protected static final short SEC_OID_DES_EDE3_CBC=13;
protected static final short CKM_DES3_CBC_PAD=14;
protected static final short CKM_DES_KEY_GEN=15;
protected static final short CKM_DES3_KEY_GEN=16;
protected static final short CKM_RC4_KEY_GEN=17;
protected static final short SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC=18;
protected static final short SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC=19;
protected static final short SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC=20;
protected static final short
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4=21;
protected static final short
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4=22;
protected static final short
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC=23;
protected static final short SEC_OID_MD2=24;
protected static final short SEC_OID_MD5=25;
protected static final short SEC_OID_SHA1=26;
protected static final short CKM_SHA_1_HMAC=27;
protected static final short
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC=28;
protected static final short
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC=29;
protected static final short SEC_OID_RC2_CBC=30;
protected static final short CKM_PBA_SHA1_WITH_SHA1_HMAC=31;
// AES
protected static final short CKM_AES_KEY_GEN=32;
protected static final short CKM_AES_ECB=33;
protected static final short CKM_AES_CBC=34;
protected static final short CKM_AES_CBC_PAD=35;
protected static final short CKM_RC2_CBC_PAD=36;
protected static final short CKM_RC2_KEY_GEN=37;
//FIPS 180-2
protected static final short SEC_OID_SHA256=38;
protected static final short SEC_OID_SHA384=39;
protected static final short SEC_OID_SHA512=40;
protected static final short SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION=41;
protected static final short SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION=42;
protected static final short SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION=43;
protected static final short SEC_OID_ANSIX962_EC_PUBLIC_KEY=44;
protected static final short SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE=45;
protected static final short CKM_EC_KEY_PAIR_GEN=46;
protected static final short SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE=47;
protected static final short SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE=48;
protected static final short SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE=49;
protected static final short SEC_OID_HMAC_SHA256=50;
protected static final short SEC_OID_HMAC_SHA384=51;
protected static final short SEC_OID_HMAC_SHA512=52;
//PKCS5 V2
protected static final short SEC_OID_PKCS5_PBKDF2=53;
protected static final short SEC_OID_PKCS5_PBES2=54;
protected static final short SEC_OID_PKCS5_PBMAC1=55;
protected static final short SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST=56;
protected static final short CKM_NSS_AES_KEY_WRAP=57;
protected static final short CKM_NSS_AES_KEY_WRAP_PAD=58;
// AES Encryption Algorithms
protected static final short SEC_OID_AES_128_ECB = 59;
protected static final short SEC_OID_AES_128_CBC = 60;
protected static final short SEC_OID_AES_192_ECB = 61;
protected static final short SEC_OID_AES_192_CBC = 62;
protected static final short SEC_OID_AES_256_ECB = 63;
protected static final short SEC_OID_AES_256_CBC = 64;
}
jss-4.4.3/jss/org/mozilla/jss/crypto/AlreadyInitializedException.java 0000664 0000000 0000000 00000001062 13261450000 0025754 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* This exception is thrown if an initialization operation
* is attempted on something that is already initialized.
*/
public class AlreadyInitializedException extends java.lang.Exception {
public AlreadyInitializedException() {}
public AlreadyInitializedException(String mesg) {
super(mesg);
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/BadPaddingException.java 0000664 0000000 0000000 00000000743 13261450000 0024167 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* @deprecated Use javax.crypto.BadPaddingException.
*/
public class BadPaddingException extends Exception {
public BadPaddingException() {
super();
}
public BadPaddingException(String msg) {
super(msg);
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/Cipher.java 0000664 0000000 0000000 00000016145 13261450000 0021550 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.security.InvalidKeyException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.InvalidAlgorithmParameterException;
import org.mozilla.jss.util.Assert;
/**
* A context for performing symmetric encryption and decryption.
* First, the context must be initialized. Then, it can be updated
* with input through zero or more calls to Instances of CryptoToken are obtained from CryptoManager.
* @see org.mozilla.jss.CryptoManager
*/
public interface CryptoToken {
//
// SERVICES
//
/**
* Creates a Signature object, which can perform signing and signature
* verification. Signing and verification cryptographic operations will
* take place on this token. The signing key must be located on this
* token.
*
* @param algorithm The algorithm used for the signing/verification.
* @exception java.security.NoSuchAlgorithmException If the given
* algorithm is not supported by this provider.
*/
public abstract org.mozilla.jss.crypto.Signature
getSignatureContext(SignatureAlgorithm algorithm)
throws java.security.NoSuchAlgorithmException, TokenException;
/**
* Creates a Digest object. Digesting cryptographic operations will
* take place on this token.
*
* @param algorithm The algorithm used for digesting.
* @exception java.security.NoSuchAlgorithmException If this provider
* does not support the given algorithm.
*/
public abstract JSSMessageDigest
getDigestContext(DigestAlgorithm algorithm)
throws java.security.NoSuchAlgorithmException, DigestException;
// !!! MAC ???
/**
* Creates a Cipher object, which can be used for encryption and
* decryption. Cryptographic operations will take place on this token.
* The keys used in the operations must be located on this token.
*
* @param algorithm The algorithm used for encryption/decryption.
* @exception java.security.NoSuchAlgorithmException If this provider
* does not support the given algorithm.
*/
public abstract Cipher
getCipherContext(EncryptionAlgorithm algorithm)
throws java.security.NoSuchAlgorithmException, TokenException;
public abstract SymmetricKeyDeriver getSymmetricKeyDeriver()
throws TokenException;
public abstract KeyWrapper
getKeyWrapper(KeyWrapAlgorithm algorithm)
throws java.security.NoSuchAlgorithmException, TokenException;
/**
* Returns a Random Number Generator implemented on this token.
*
* @exception org.mozilla.jss.crypto.ServiceNotProvidedException If this token
* does not perform random number generation
*/
/*
public abstract SecureRandom getRandomGenerator()
throws NotImplementedException, TokenException;
*/
// !!! Derive Keys ???
/**
* Creates a KeyGenerator object, which can be used to generate
* symmetric encryption keys. Any keys generated with this KeyGenerator
* will be generated on this token.
*
* @param algorithm The algorithm that the keys will be used with.
* @exception java.security.NoSuchAlgorithmException If this token does not
* support the given algorithm.
*/
public abstract KeyGenerator
getKeyGenerator(KeyGenAlgorithm algorithm)
throws java.security.NoSuchAlgorithmException, TokenException;
/**
* Clones a SymmetricKey from a different token onto this token.
*
* @exception SymmetricKey.NotExtractableException If the key material
* cannot be extracted from the current token.
* @exception InvalidKeyException If the owning token cannot process
* the key to be cloned.
*/
public SymmetricKey cloneKey(SymmetricKey key)
throws SymmetricKey.NotExtractableException,
InvalidKeyException, TokenException;
/**
* Creates a KeyPairGenerator object, which can be used to generate
* key pairs. Any keypairs generated with this generator will be generated
* on this token.
*
* @param algorithm The algorithm that the keys will be used with (RSA,
* DSA, EC, etc.)
* @exception java.security.NoSuchAlgorithmException If this token does
* not support the given algorithm.
*/
public abstract KeyPairGenerator
getKeyPairGenerator(KeyPairAlgorithm algorithm)
throws java.security.NoSuchAlgorithmException, TokenException;
/**
* Generates a b64 encoded PKCS10 blob used for making cert
* request. Begin/End brackets included.
* @param subject subject dn of the certificate
* @param keysize size of the key
* @param keyType "rsa" or "dsa"
* @param P The DSA prime parameter
* @param Q The DSA sub-prime parameter
* @param G The DSA base parameter
* @return base64 encoded pkcs10 certificate request with
* Begin/end brackets
*/
public abstract String generateCertRequest(String subject, int
keysize,
String keyType,
byte[] P, byte[] Q,
byte[] G)
throws TokenException, InvalidParameterException,
PQGParamGenException;
/**
* Determines whether this token supports the given algorithm.
*
* @param alg A JSS algorithm. Note that for Signature, a token may
* fail to support a specific SignatureAlgorithm (such as
* RSASignatureWithMD5Digest) even though it does support the
* generic algorithm (RSASignature). In this case, the signature
* operation will be performed on that token, but the digest
* operation will be performed on the internal token.
* @return true if the token supports the algorithm.
*/
public boolean doesAlgorithm(Algorithm alg);
/**
* Login to the token. If a token is logged in, it will not trigger
* password callbacks.
*
* @param pwcb The password callback for this token.
* @exception IncorrectPasswordException If the supplied password is
* incorrect.
* @see #setLoginMode
* @see org.mozilla.jss.CryptoManager#setPasswordCallback
*/
public abstract void login(PasswordCallback pwcb)
throws IncorrectPasswordException, TokenException;
/**
* Logout of the token.
*
*/
public abstract void logout() throws TokenException;
/**
* Login once, never need to re-enter the password until you log out.
*/
public static final int ONE_TIME=0;
/**
* Need to re-login after a period of time.
* @see org.mozilla.jss.crypto.CryptoToken#setLoginTimeoutMinutes
*/
public static final int TIMEOUT=1;
/**
* Need to provide a password before each crypto operation.
*/
public static final int EVERY_TIME=2;
/**
* Returns the login mode of this token: ONE_TIME, TIMEOUT, or
* EVERY_TIME. The default is ONE_TIME.
* @see #getLoginTimeoutMinutes
* @exception TokenException If an error occurs on the token.
*/
public abstract int getLoginMode() throws TokenException;
/**
* Sets the login mode of this token.
*
* @param mode ONE_TIME, TIMEOUT, or EVERY_TIME
* @exception TokenException If this mode is not supported by this token,
* or an error occurs on the token.
* @see #login
* @see #setLoginTimeoutMinutes
*/
public abstract void setLoginMode(int mode) throws TokenException;
/**
* Returns the login timeout period. The timeout is only used if the
* login mode is TIMEOUT.
*
* @see #getLoginMode
* @exception TokenException If an error occurs on the token.
*/
public abstract int getLoginTimeoutMinutes() throws TokenException;
/**
* Sets the timeout period for logging in. This will only be used
* if the login mode is TIMEOUT.
*
* @exception TokenException If timeouts are not supported by this
* token, or an error occurs on the token.
* @see #setLoginMode
*/
public abstract void setLoginTimeoutMinutes(int timeoutMinutes)
throws TokenException;
/**
* Find out if the token is currently logged in.
*
* @see #login
* @see #logout
*/
public boolean isLoggedIn() throws TokenException;
/**
* returns true if this token needs to be logged into before
* it can be used.
*
* @see #login
* @see #logout
*/
public boolean needsLogin() throws TokenException;
/**
* Initialize the password of this token.
*
* @param securityOfficerPW A callback to obtain the password of the
* SecurityOfficer. Pass in a NullPasswordCallback if there is
* no security officer password. Must not be null.
* @param userPW A callback to obtain the new password for this token.
* Must not be null.
* @exception IncorrectPasswordException If the supplied security officer
* password is incorrect.
* @exception AlreadyInitializedException If the token only allows one
* password initialization, and it has already occurred.
* @exception TokenException If an error occurs on the token.
*/
public abstract void
initPassword(PasswordCallback securityOfficerPW, PasswordCallback userPW)
throws IncorrectPasswordException, AlreadyInitializedException,
TokenException;
/**
* Determine whether the password has been initialized yet. Some tokens
* (such as the Netscape Internal Key Token) don't allow initializing
* the PIN more than once.
*
* @exception TokenException If an error occurs on the token.
*/
public abstract boolean
passwordIsInitialized() throws TokenException;
/**
* Change the password of this token.
*
* @exception IncorrectPasswordException If the supplied old password is
* incorrect.
* @param oldpw A callback (which could be just a Password) to retrieve
* the current password.
* @param newpw A callback (which could be just a Password) to retrieve
* the new password.
*/
public abstract void
changePassword(PasswordCallback oldpw, PasswordCallback newpw)
throws IncorrectPasswordException, TokenException;
/**
* Obtain the nickname, or label, of this token.
*
* @exception TokenException If an error occurs on the token.
*/
public abstract String getName() throws TokenException;
/**
* Get the CryptoStore interface to this token's objects.
*/
public abstract CryptoStore getCryptoStore();
/**
* Deep comparison operation. Use this, rather than ==, to determine
* whether two CryptoTokens are the same.
*/
public boolean equals(Object object);
/**
* Determines whether this token is currently present.
* This could return false if the token is a smart card that was
* removed from its slot.
*/
public boolean isPresent();
}
jss-4.4.3/jss/org/mozilla/jss/crypto/DigestAlgorithm.java 0000664 0000000 0000000 00000005511 13261450000 0023417 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.util.Hashtable;
import java.security.NoSuchAlgorithmException;
import org.mozilla.jss.asn1.*;
public class DigestAlgorithm extends Algorithm {
// The size in bytes of the output of this hash.
private int outputSize;
protected DigestAlgorithm(int oidIndex, String name,
OBJECT_IDENTIFIER oid, int outputSize)
{
super(oidIndex, name, oid);
this.outputSize = outputSize;
// only store the first algorithm for a given oid. More than one
// alg might share the same oid, such as from child classes.
if( oid != null && oidMap.get(oid)==null ) {
oidMap.put(oid, this);
}
}
///////////////////////////////////////////////////////////////////////
// OID mapping
///////////////////////////////////////////////////////////////////////
private static Hashtable oidMap = new Hashtable();
public static DigestAlgorithm fromOID(OBJECT_IDENTIFIER oid)
throws NoSuchAlgorithmException
{
Object alg = oidMap.get(oid);
if( alg == null ) {
throw new NoSuchAlgorithmException();
} else {
return (DigestAlgorithm) alg;
}
}
/**
* Returns the output size in bytes for this algorithm.
*/
public int getOutputSize() {
return outputSize;
}
/**
* The MD2 digest algorithm, from RSA.
*/
public static final DigestAlgorithm MD2 = new DigestAlgorithm
(SEC_OID_MD2, "MD2", OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(2), 16 );
/**
* The MD5 digest algorithm, from RSA.
*/
public static final DigestAlgorithm MD5 = new DigestAlgorithm
(SEC_OID_MD5, "MD5", OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(5), 16 );
/**
* The SHA-1 digest algorithm, from Uncle Sam.
*/
public static final DigestAlgorithm SHA1 = new DigestAlgorithm
(SEC_OID_SHA1, "SHA-1", OBJECT_IDENTIFIER.ALGORITHM.subBranch(26), 20);
/*
* The SHA-256 digest Algorithm from FIPS 180-2
*/
public static final DigestAlgorithm SHA256 = new DigestAlgorithm
(SEC_OID_SHA256, "SHA-256", OBJECT_IDENTIFIER.HASH_ALGORITHM.subBranch(1), 32);
/*
* The SHA-384 digest Algorithm from FIPS 180-2
*/
public static final DigestAlgorithm SHA384 = new DigestAlgorithm
(SEC_OID_SHA384, "SHA-384", OBJECT_IDENTIFIER.HASH_ALGORITHM.subBranch(2), 48);
/*
* The SHA-512 digest Algorithm from FIPS 180-2
*/
public static final DigestAlgorithm SHA512 = new DigestAlgorithm
(SEC_OID_SHA512, "SHA-512", OBJECT_IDENTIFIER.HASH_ALGORITHM.subBranch(3), 64);
}
jss-4.4.3/jss/org/mozilla/jss/crypto/EncryptionAlgorithm.java 0000664 0000000 0000000 00000032275 13261450000 0024341 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.security.NoSuchAlgorithmException;
import org.mozilla.jss.asn1.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.RC2ParameterSpec;
import java.util.*;
/**
* An algorithm for performing symmetric encryption.
*/
public class EncryptionAlgorithm extends Algorithm {
public static class Mode {
private String name;
private static Hashtable nameHash = new Hashtable();
private Mode() { }
private Mode(String name) {
this.name = name;
nameHash.put(name.toLowerCase(), this);
}
public static Mode fromString(String name)
throws NoSuchAlgorithmException
{
Mode m = (Mode) nameHash.get(name.toLowerCase());
if( m == null ) {
throw new NoSuchAlgorithmException(
"Unrecognized mode \"" + name + "\"");
}
return m;
}
public String toString() {
return name;
}
public static final Mode NONE = new Mode("NONE");
public static final Mode ECB = new Mode("ECB");
public static final Mode CBC = new Mode("CBC");
}
public static class Alg {
private String name;
private static Hashtable nameHash = new Hashtable();
private Alg() { }
private Alg(String name) {
this.name = name;
nameHash.put(name.toLowerCase(), this);
}
private static Alg fromString(String name)
throws NoSuchAlgorithmException
{
Alg a = (Alg) nameHash.get(name.toLowerCase());
if( a == null ) {
throw new NoSuchAlgorithmException("Unrecognized algorithm \""
+ name + "\"");
}
return a;
}
public String toString() {
return name;
}
public static final Alg RC4 = new Alg("RC4");
public static final Alg DES = new Alg("DES");
public static final Alg DESede = new Alg("DESede");
public static final Alg AES = new Alg("AES");
public static final Alg RC2 = new Alg("RC2");
}
public static class Padding {
private String name;
private static Hashtable nameHash = new Hashtable();
private Padding() { }
private Padding(String name) {
this.name = name;
nameHash.put(name.toLowerCase(), this);
}
public String toString() {
return name;
}
public static Padding fromString(String name)
throws NoSuchAlgorithmException
{
Padding p = (Padding) nameHash.get(name.toLowerCase());
if( p == null ) {
throw new NoSuchAlgorithmException("Unrecognized Padding " +
"type \"" + name + "\"");
}
return p;
}
public static final Padding NONE = new Padding("NoPadding");
public static final Padding PKCS5 = new Padding("PKCS5Padding");
}
private static String makeName(Alg alg, Mode mode, Padding padding) {
StringBuffer buf = new StringBuffer();
buf.append(alg.toString());
buf.append('/');
buf.append(mode.toString());
buf.append('/');
buf.append(padding.toString());
return buf.toString();
}
protected EncryptionAlgorithm(int oidTag, Alg alg, Mode mode,
Padding padding, Class paramClass, int blockSize,
OBJECT_IDENTIFIER oid, int keyStrength)
{
super(oidTag, makeName(alg, mode, padding), oid, paramClass);
this.alg = alg;
this.mode = mode;
this.padding = padding;
this.blockSize = blockSize;
if(oid!=null) {
oidMap.put(oid, this);
}
if( name != null ) {
nameMap.put(name.toLowerCase(), this);
}
this.keyStrength = keyStrength;
algList.addElement(this);
}
protected EncryptionAlgorithm(int oidTag, Alg alg, Mode mode,
Padding padding, Class []paramClasses, int blockSize,
OBJECT_IDENTIFIER oid, int keyStrength)
{
super(oidTag, makeName(alg, mode, padding), oid, paramClasses);
this.alg = alg;
this.mode = mode;
this.padding = padding;
this.blockSize = blockSize;
if(oid!=null) {
oidMap.put(oid, this);
}
if( name != null ) {
nameMap.put(name.toLowerCase(), this);
}
this.keyStrength = keyStrength;
algList.addElement(this);
}
private int blockSize;
private Alg alg;
private Mode mode;
private Padding padding;
private int keyStrength;
/**
* Returns the base algorithm, without the parameters. For example,
* the base algorithm of "AES/CBC/NoPadding" is "AES".
*/
public Alg getAlg() {
return alg;
}
/**
* Returns the mode of this algorithm.
*/
public Mode getMode() {
return mode;
}
/**
* Returns the padding type of this algorithm.
*/
public Padding getPadding() {
return padding;
}
/**
* Returns the key strength of this algorithm in bits. Algorithms that
* use continuously variable key sizes (such as RC4) will return 0 to
* indicate they can use any key size.
*/
public int getKeyStrength() {
return keyStrength;
}
///////////////////////////////////////////////////////////////////////
// mapping
///////////////////////////////////////////////////////////////////////
private static Hashtable oidMap = new Hashtable();
private static Hashtable nameMap = new Hashtable();
private static Vector algList = new Vector();
public static EncryptionAlgorithm fromOID(OBJECT_IDENTIFIER oid)
throws NoSuchAlgorithmException
{
Object alg = oidMap.get(oid);
if( alg == null ) {
throw new NoSuchAlgorithmException("OID: " + oid.toString());
} else {
return (EncryptionAlgorithm) alg;
}
}
// Note: after we remove this deprecated method, we can remove
// nameMap.
/**
* @deprecated This method is deprecated because algorithm strings
* don't contain key length, which is necessary to distinguish between
* AES algorithms.
*/
public static EncryptionAlgorithm fromString(String name)
throws NoSuchAlgorithmException
{
Object alg = nameMap.get(name.toLowerCase());
if( alg == null ) {
throw new NoSuchAlgorithmException();
} else {
return (EncryptionAlgorithm) alg;
}
}
public static EncryptionAlgorithm lookup(String algName, String modeName,
String paddingName, int keyStrength)
throws NoSuchAlgorithmException
{
int len = algList.size();
Alg alg = Alg.fromString(algName);
Mode mode = Mode.fromString(modeName);
Padding padding = Padding.fromString(paddingName);
int i;
for(i = 0; i < len; ++i ) {
EncryptionAlgorithm cur =
(EncryptionAlgorithm) algList.elementAt(i);
if( cur.alg == alg && cur.mode == mode && cur.padding == padding ) {
if( cur.keyStrength == 0 || cur.keyStrength == keyStrength ) {
break;
}
}
}
if( i == len ) {
throw new NoSuchAlgorithmException(algName + "/" + modeName + "/"
+ paddingName + " with key strength " + keyStrength +
" not found");
}
return (EncryptionAlgorithm) algList.elementAt(i);
}
/**
* The blocksize of the algorithm in bytes. Stream algorithms (such as
* RC4) have a blocksize of 1.
*/
public int getBlockSize() {
return blockSize;
}
/**
* Returns PKCS #5 algorithms require exactly 8 bytes of salt. PKCS #12
* algorithms take
* a variable length, but recommend that the salt length be at least
* as long as the output of the hash function. For SHA-1, the output
* length is 20 bytes.
*/
public int getSaltLength() {
return saltLength;
}
///////////////////////////////////////////////////////////////////////
// OIDs
///////////////////////////////////////////////////////////////////////
private static final OBJECT_IDENTIFIER PKCS5 = OBJECT_IDENTIFIER.PKCS5;
private static final OBJECT_IDENTIFIER PKCS12_PBE =
OBJECT_IDENTIFIER.PKCS12.subBranch(1);
///////////////////////////////////////////////////////////////////////
// OID mapping
///////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
// PKCS 5 v2
public static final PBEAlgorithm
PBE_PKCS5_PBKDF2 = new PBEAlgorithm(
SEC_OID_PKCS5_PBKDF2, "PBKDF2", 128,
PKCS5.subBranch(12), EncryptionAlgorithm.AES_128_CBC, 8 );
//////////////////////////////////////////////////////////////
// PKCS 5 v2
public static final PBEAlgorithm
PBE_PKCS5_PBES2 = new PBEAlgorithm(
SEC_OID_PKCS5_PBES2, "PBES2", 128,
PKCS5.subBranch(13), EncryptionAlgorithm.AES_128_CBC, 8 );
//////////////////////////////////////////////////////////////
// PKCS 5 v2
public static final PBEAlgorithm
PBE_PKCS5_PBMAC1 = new PBEAlgorithm(
SEC_OID_PKCS5_PBMAC1, "PBMAC1", 128,
PKCS5.subBranch(14), EncryptionAlgorithm.AES_128_CBC, 8 );
//////////////////////////////////////////////////////////////
public static final PBEAlgorithm
PBE_MD2_DES_CBC = new PBEAlgorithm(
SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC, "PBE/MD2/DES/CBC", 56,
PKCS5.subBranch(1), EncryptionAlgorithm.DES_CBC, 8 );
//////////////////////////////////////////////////////////////
public static final PBEAlgorithm
PBE_MD5_DES_CBC = new PBEAlgorithm(
SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC, "PBE/MD5/DES/CBC", 56,
PKCS5.subBranch(3), EncryptionAlgorithm.DES_CBC, 8 );
//////////////////////////////////////////////////////////////
public static final PBEAlgorithm
PBE_SHA1_DES_CBC = new PBEAlgorithm(
SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC, "PBE/SHA1/DES/CBC", 56,
PKCS5.subBranch(10), EncryptionAlgorithm.DES_CBC, 8 );
//////////////////////////////////////////////////////////////
public static final PBEAlgorithm
PBE_SHA1_RC4_128 = new PBEAlgorithm(
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4,
"PBE/SHA1/RC4-128", 128, PKCS12_PBE.subBranch(1),
EncryptionAlgorithm.RC4, 20 );
//////////////////////////////////////////////////////////////
public static final PBEAlgorithm
PBE_SHA1_RC4_40 = new PBEAlgorithm(
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4,
"PBE/SHA1/RC4-40", 40, PKCS12_PBE.subBranch(2),
EncryptionAlgorithm.RC4, 20 );
//////////////////////////////////////////////////////////////
public static final PBEAlgorithm
PBE_SHA1_DES3_CBC = new PBEAlgorithm(
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC,
"PBE/SHA1/DES3/CBC", 168, PKCS12_PBE.subBranch(3),
EncryptionAlgorithm.DES3_CBC, 20 );
//////////////////////////////////////////////////////////////
public static final PBEAlgorithm
PBE_SHA1_RC2_128_CBC = new PBEAlgorithm(
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC,
"PBE/SHA1/RC2-128", 128, PKCS12_PBE.subBranch(5),
EncryptionAlgorithm.RC2_CBC, 20 );
//////////////////////////////////////////////////////////////
public static final PBEAlgorithm
PBE_SHA1_RC2_40_CBC = new PBEAlgorithm(
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC,
"PBE/SHA1/RC2-40", 40, PKCS12_PBE.subBranch(6),
EncryptionAlgorithm.RC2_CBC, 20 );
}
jss-4.4.3/jss/org/mozilla/jss/crypto/PBEKeyGenParams.java 0000664 0000000 0000000 00000010544 13261450000 0023210 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import org.mozilla.jss.util.Password;
public class PBEKeyGenParams implements AlgorithmParameterSpec, KeySpec {
private Password pass;
private byte[] salt;
private int iterations;
private EncryptionAlgorithm encryptionAlgorithm = EncryptionAlgorithm.DES3_CBC;
private PBEKeyGenParams() { }
static private final int DEFAULT_SALT_LENGTH = 8;
static private final int DEFAULT_ITERATIONS = 1;
/**
* Creates PBE parameters.
*
* @param pass The password. It will be cloned, so the
* caller is still responsible for clearing it. It must not be null.
* @param salt The salt for the PBE algorithm. Will not be cloned.
* Must not be null. It is the responsibility of the caller to
* use the right salt length for the algorithm. Most algorithms
* use 8 bytes of salt.
* @param iterations The iteration count for the PBE algorithm.
*/
public PBEKeyGenParams(Password pass, byte[] salt, int iterations) {
if(pass==null || salt==null) {
throw new NullPointerException();
}
this.pass = (Password) pass.clone();
this.salt = salt;
this.iterations = iterations;
}
/**
* Creates PBE parameters using default encryption algorithm
* (DES3_EDE3_CBC).
*
* @param pass The password. It will be cloned, so the
* caller is still responsible for clearing it. It must not be null.
* @param salt The salt for the PBE algorithm. Will not be cloned.
* Must not be null. It is the responsibility of the caller to
* use the right salt length for the algorithm. Most algorithms
* use 8 bytes of salt.
* @param iterations The iteration count for the PBE algorithm.
*/
public PBEKeyGenParams(char[] pass, byte[] salt, int iterations) {
if(pass==null || salt==null) {
throw new NullPointerException();
}
this.pass = new Password( (char[]) pass.clone() );
this.salt = salt;
this.iterations = iterations;
}
/**
* Creates PBE parameters using default encryption algorithm
* (DES3_EDE3_CBC).
*
* @param pass The password. It will be cloned, so the
* caller is still responsible for clearing it. It must not be null.
* @param salt The salt for the PBE algorithm. Will not be cloned.
* Must not be null. It is the responsibility of the caller to
* use the right salt length for the algorithm. Most algorithms
* use 8 bytes of salt.
* @param iterations The iteration count for the PBE algorithm.
* @param encAlg The encryption algorithm. This is used with SOME
* PBE algorithms for determining the KDF output length.
*/
public PBEKeyGenParams(
char[] pass, byte[] salt, int iterations,
EncryptionAlgorithm encAlg) {
if (pass == null || salt == null) {
throw new NullPointerException();
}
this.pass = new Password((char[]) pass.clone());
this.salt = salt;
this.iterations = iterations;
if (encAlg != null)
this.encryptionAlgorithm = encAlg;
}
/**
* Returns a reference to the password, not a copy.
*/
public Password getPassword() {
return pass;
}
/**
* Returns a reference to the salt.
*/
public byte[] getSalt() {
return salt;
}
/**
* Returns the iteration count.
*/
public int getIterations() {
return iterations;
}
/**
* The encryption algorithm is used with SOME PBE algorithms for
* determining the KDF output length.
*/
public EncryptionAlgorithm getEncryptionAlgorithm() {
return encryptionAlgorithm;
}
/**
* Clears the password. This should be called when this object is no
* longer needed so the password is not left around in memory.
*/
public void clear() {
pass.clear();
}
protected void finalize() throws Throwable {
pass.clear();
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/PQGParamGenException.java 0000664 0000000 0000000 00000000610 13261450000 0024245 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
public class PQGParamGenException extends Exception {
public PQGParamGenException() {}
public PQGParamGenException(String msg) { super(msg); }
}
jss-4.4.3/jss/org/mozilla/jss/crypto/PQGParams.c 0000664 0000000 0000000 00000024344 13261450000 0021432 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "_jni/org_mozilla_jss_crypto_PQGParams.h"
#include This class has two main purposes:
* generating PQG parameters and verifying PQG parameters. To generate
* PQG parameters, call one of the static It is necessary to call BigInteger adds an extra sign bit to the beginning of its byte
* array representation. In some cases this will cause the size
* of the byte array to increase, which may be unacceptable for some
* applications. This function returns a minimal byte array representing
* the BigInteger without extra sign bits.
*
* @return An unsigned, big-endian byte array representation
* of a BigInteger.
*/
public static byte[] BigIntegerToUnsignedByteArray(BigInteger big) {
byte[] ret;
// big must not be negative
Assert._assert(big.signum() != -1);
// bitLength is the size of the data without the sign bit. If
// it exactly fills an integral number of bytes, that means a whole
// new byte will have to be added to accomodate the sign bit. In
// this case we need to remove the first byte.
if(big.bitLength() % 8 == 0) {
byte[] array = big.toByteArray();
// The first byte should just be sign bits
Assert._assert( array[0] == 0 );
ret = new byte[array.length-1];
System.arraycopy(array, 1, ret, 0, ret.length);
} else {
ret = big.toByteArray();
}
return ret;
}
/**
* Verifies the PQG parameters using the seed, counter, and H values.
* @return true if the parameters verified correctly, false if they
* did not verify.
*/
public boolean paramsAreValid() {
return paramsAreValidNative(BigIntegerToUnsignedByteArray( getP() ),
BigIntegerToUnsignedByteArray( getQ() ),
BigIntegerToUnsignedByteArray( getG() ),
BigIntegerToUnsignedByteArray( seed ),
counter,
BigIntegerToUnsignedByteArray( H ));
}
private native boolean paramsAreValidNative(byte[] P, byte[] Q, byte[]G,
byte[] seed, int counter, byte[] H);
/**
* @return The Seed used to generate P, Q, and G.
*/
public BigInteger getSeed() {
return seed;
}
/**
* @return The Counter (C) used to generate P, Q, and G.
*/
public int getCounter() {
return counter;
}
/**
* @return The H value used to generate P, Q, and G.
*/
public BigInteger getH() {
return H;
}
private BigInteger seed;
private int counter;
private BigInteger H;
}
jss-4.4.3/jss/org/mozilla/jss/crypto/PrivateKey.java 0000664 0000000 0000000 00000007500 13261450000 0022414 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
import java.util.Hashtable;
import org.mozilla.jss.util.Assert;
import java.security.NoSuchAlgorithmException;
/**
* Private Keys used by JSS. All the private keys handled by JSS are
* of this type, which is a subtype of java.security.PrivateKey.
*/
public interface PrivateKey extends java.security.PrivateKey
{
public static final Type RSA = Type.RSA;
public static final Type DSA = Type.DSA;
public static final Type EC = Type.EC;
public static final Type DiffieHellman = Type.DiffieHellman;
/**
* Returns the type (RSA or DSA) of this private key.
*/
public Type getType();
/**
* Returns the unique ID of this key. Unique IDs can be used to match
* certificates to keys.
*
* @see org.mozilla.jss.crypto.TokenCertificate#getUniqueID
* @deprecated This ID is based on an implementation that might change.
* If this functionality is required, it should be provided in
* another way, such as a function that directly matches a cert and
* key.
*/
public byte[] getUniqueID() throws TokenException;
/**
* Returns the size, in bits, of the modulus of an RSA key.
* Returns -1 for other types of keys.
*/
public int getStrength();
/**
* Returns the CryptoToken that owns this private key. Cryptographic
* operations with this key may only be performed on the token that
* owns the key.
*/
public CryptoToken getOwningToken();
public static final class Type {
private OBJECT_IDENTIFIER oid;
private String name;
private int pkcs11Type;
private Type() { }
private Type(OBJECT_IDENTIFIER oid, String name, int pkcs11Type) {
this.oid = oid;
this.name = name;
Object old = oidMap.put(oid, this);
this.pkcs11Type = pkcs11Type;
Assert._assert( old == null );
}
private static Hashtable oidMap = new Hashtable();
public static Type fromOID(OBJECT_IDENTIFIER oid)
throws NoSuchAlgorithmException
{
Object obj = oidMap.get(oid);
if( obj == null ) {
throw new NoSuchAlgorithmException();
}
return (Type) obj;
}
/**
* Returns a string representation of the algorithm, such as
* "RSA", "DSA", or "EC".
*/
public String toString() {
return name;
}
public OBJECT_IDENTIFIER toOID() {
return oid;
}
public int getPKCS11Type() {
return pkcs11Type;
}
// OID for DiffieHellman, from RFC 2459 7.3.2.
public static OBJECT_IDENTIFIER DH_OID =
new OBJECT_IDENTIFIER( new long[] {1, 2, 840, 10046, 2, 1} );
// From PKCS #11
private static int CKK_RSA = 0x0;
private static int CKK_DSA = 0x1;
private static int CKK_DH = 0x2;
private static int CKK_EC = 0x3;
private static int CKK_X9_42_DH = 0x4;
private static int CKK_KEA = 0x5;
public static final Type RSA = new Type(
OBJECT_IDENTIFIER.PKCS1.subBranch(1), "RSA", CKK_RSA );
public static final Type DSA = new Type(
Algorithm.ANSI_X9_ALGORITHM.subBranch(1), "DSA", CKK_DSA);
public static final Type EC = new Type(
Algorithm.ANSI_X962_OID.subBranch(2).subBranch(1), "EC", CKK_EC);
public static final Type DiffieHellman = new Type(
DH_OID, "DiffieHellman", CKK_DH );
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/RSAParameterSpec.java 0000664 0000000 0000000 00000002273 13261450000 0023434 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.security.spec.AlgorithmParameterSpec;
import java.math.BigInteger;
/**
* This class specifies the parameters used for generating an RSA key pair.
*/
public class RSAParameterSpec implements AlgorithmParameterSpec {
/**
* Creates a new RSAParameterSpec with the specified parameter values.
* @param keySize The size of the modulus in bits.
* @param publicExponent The public exponent e. Common values
* are 3, 17, and 65537. 65537 is recommended.
*/
public RSAParameterSpec(int keySize, BigInteger publicExponent) {
this.keySize = keySize;
this.publicExponent = publicExponent;
}
/**
* Returns the size of the modulus in bits.
*/
public int getKeySize() { return keySize; }
/**
* Returns the public exponent e.
*/
public BigInteger getPublicExponent() { return publicExponent; }
private int keySize;
private BigInteger publicExponent;
}
jss-4.4.3/jss/org/mozilla/jss/crypto/SecretDecoderRing.c 0000664 0000000 0000000 00000003714 13261450000 0023170 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "_jni/org_mozilla_jss_crypto_SecretDecoderRing.h"
#include A dedicated key is used to encrypt all SecretDecoderRing data.
* The same key is used for all SDR data, and not for any other data.
* This key will be generated the first time it is needed.
*
* The cipher used is DES3-EDE (Triple-DES) in CBC mode. The ciphertext
* is DER-encoded in the following ASN.1 data structure:
* You must set the password on the Internal Key Storage Token
* (aka software token, key3.db) before you use the SecretDecoderRing.
*/
public class SecretDecoderRing {
public static final String encodingFormat = "UTF-8";
/**
* Encrypts the given plaintext with the Secret Decoder Ring key stored
* in the NSS key database.
*/
public native byte[] encrypt(byte[] plaintext)
throws TokenException;
/**
* Encrypts the given plaintext string with the Secret Decoder Ring key
* stored in the NSS key database.
*/
public byte[] encrypt(String plaintext) throws TokenException {
try {
return encrypt(plaintext.getBytes(encodingFormat));
} catch(UnsupportedEncodingException e) {
// this shouldn't happen, because we use a universally-supported
// charset
throw new RuntimeException(e.getMessage());
}
}
/**
* Decrypts the given ciphertext with the Secret Decoder Ring key stored
* in the NSS key database.
*/
public native byte[] decrypt(byte[] ciphertext)
throws TokenException;
/**
* Decrypts the given ciphertext with the Secret Decoder Ring key stored
* in the NSS key database, returning the original plaintext string.
*/
public String decryptToString(byte[] ciphertext)
throws TokenException {
try {
return new String(decrypt(ciphertext), encodingFormat);
} catch(UnsupportedEncodingException e) {
// this shouldn't happen, because we use a universally-supported
// charset
throw new RuntimeException(e.getMessage());
}
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/SecretKeyFacade.java 0000664 0000000 0000000 00000001170 13261450000 0023310 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
public class SecretKeyFacade implements javax.crypto.SecretKey {
public SymmetricKey key;
public SecretKeyFacade(SymmetricKey symk) {
key = symk;
}
public String getAlgorithm() {
return key.getAlgorithm();
}
public byte[] getEncoded() {
return key.getEncoded();
}
public String getFormat() {
return key.getFormat();
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/ShortBufferException.java 0000664 0000000 0000000 00000000620 13261450000 0024435 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* This class is a placeholder for javax.crypto.ShortBufferException until
* we move to JDK 1.2.
*/
public class ShortBufferException extends Exception { }
jss-4.4.3/jss/org/mozilla/jss/crypto/Signature.java 0000664 0000000 0000000 00000013426 13261450000 0022276 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import org.mozilla.jss.util.*;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
/**
* A class for producing and verifying digital signatures.
* Instances of this class can be obtain from When you unwrap a symmetric key, you must specify which one of these
* operations it will be used to perform.
*/
public final static class Usage {
private Usage() { }
private Usage(int val) { this.val = val;}
private int val;
public int getVal() { return val; }
// these enums must match the JSS_symkeyUsage list in Algorithm.c
// and the opFlagForUsage list in PK11KeyGenerator.java
public static final Usage ENCRYPT = new Usage(0);
public static final Usage DECRYPT = new Usage(1);
public static final Usage WRAP = new Usage(2);
public static final Usage UNWRAP = new Usage(3);
public static final Usage SIGN = new Usage(4);
public static final Usage VERIFY = new Usage(5);
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/SymmetricKeyDeriver.java 0000664 0000000 0000000 00000006307 13261450000 0024303 0 ustar 00root root 0000000 0000000 /* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Netscape Security Services for Java.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.jss.crypto;
import java.security.spec.AlgorithmParameterSpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.PublicKey;
import java.security.InvalidKeyException;
public interface SymmetricKeyDeriver {
/* Use with the encrypt type mechanisms
Example: initDerive(
symKey, (PKCS11Constants.CKM_DES3_ECB_ENCRYPT_DATA) 4354L, derivationData, null,
PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE, 16);
*/
public abstract void initDerive(SymmetricKey baseKey,
long deriveMech, byte[] param, byte[] iv, long targetMech, long operation, long keySize)
throws InvalidKeyException;
/* Use with key extraction and key concatanation mechanisms
Example:
param: byte array that has the bit position of where to extract
initDerive(
derivedKey, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null,
PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,8);
initDerive(
baseSymKey,secondarySymKey, PKCS11Constants.CKM_CONCATENATE_BASE_AND_KEY,null,null,
PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,0);
*/
public abstract void initDerive(SymmetricKey baseKey,
SymmetricKey secondaryKey, long deriveMech, byte[] param, byte[] iv, long targetMech, long operation, long keySize)
throws InvalidKeyException;
public abstract SymmetricKey derive()
throws TokenException;
}
jss-4.4.3/jss/org/mozilla/jss/crypto/TokenCertificate.java 0000664 0000000 0000000 00000002341 13261450000 0023552 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* An X509 Certificate that lives on a PKCS #11 token.
* Many of the X509Certificates returned by JSS calls are actually
* TokenCertificates.
* To find out if an X509Certificate is a TokenCertificate, use
* ANY
value. An ANY is just an arbitrary
* ASN.1 value. It can be thought of as the simplest implementation of the
* ASN1Value
interface. Although they can be created
* from scratch (from raw BER), instances of ANY
are usually
* found after decoding
* with a template that has an ANY
field.
*
* ANY
supports extracting the BER encoding, or decoding
* with a different template.
*/
public class ANY implements ASN1Value {
private ANY() { }
// The complete encoding of header + contents
private byte[] encoded;
private Tag tag;
/**
* Creates an ANY value, which is just a generic ASN.1 value.
* This method is provided for efficiency if the tag is already known,
* so that we don't have to parse the encoding for it.
* @param tag The tag of this value. It must be the same as the actual tag
* contained in the encoding.
* @param encoded The complete BER encoding of this value, including
* tag, form, length, and contents.
*/
public ANY(Tag tag, byte[] encoded) {
this.encoded = encoded;
this.tag = tag;
}
/**
* Creates an ANY value, which is just a generic ASN.1 value.
* @param encoded The complete BER encoding of this value, including
* tag, form, length, and contents.
*/
public ANY(byte[] encoded) throws InvalidBERException {
try {
this.encoded = encoded;
ByteArrayInputStream bis = new ByteArrayInputStream(encoded);
ASN1Header head = new ASN1Header(bis);
this.tag = head.getTag();
} catch(IOException e) {
throw new org.mozilla.jss.util.AssertionException(
"IOException while creating ANY: "+e);
}
}
/**
* Returns the tag of this value.
*/
public Tag getTag() {
return tag;
}
/**
* Returns the complete encoding of header and contents, as passed into
* the constructor or read from a BER input stream.
*/
public byte[] getEncoded() {
return encoded;
}
/**
* Returns the ASN.1 header from the encoding.
*/
public ASN1Header getHeader() throws InvalidBERException, IOException {
if( header == null ) {
ByteArrayInputStream bis = new ByteArrayInputStream(encoded);
header = new ASN1Header(bis);
}
return header;
}
private ASN1Header header=null;
/**
* Strips out the header and returns just the contents octets of the
* encoding.
*/
private byte[] contents=null;
public byte[] getContents() throws InvalidBERException {
try {
if( contents==null ) {
ByteArrayInputStream bis = new ByteArrayInputStream(encoded);
header = new ASN1Header(bis);
contents = new byte[ bis.available() ];
if( (contents.length != header.getContentLength()) &&
( header.getContentLength() != -1 ) ) {
throw new InvalidBERException("Length of contents was not the "+
"same as the header predicted");
}
ASN1Util.readFully(contents, bis);
}
return contents;
} catch( IOException e ) {
Assert.notReached("IOException reading from byte array");
return null;
}
}
public void encode(OutputStream ostream) throws IOException {
ostream.write(encoded);
}
/**
* Decodes this ANY using the given template. This is useful if you
* originally decoded something as an ANY because you didn't know
* what it was, but now you know what it is supposed to be.
*
* @param template The template to use to decode this ANY.
* @return The output of the given template when it is fed the
* encoding of this ANY.
*/
public ASN1Value decodeWith(ASN1Template template)
throws InvalidBERException
{
try {
ByteArrayInputStream bis = new ByteArrayInputStream(encoded);
return template.decode(bis);
} catch( IOException e ) {
Assert.notReached("IOException while reading from byte array input"+
" stream");
return null;
}
}
/**
* Decodes this ANY using the given template. This is useful if you
* originally decoded something as an ANY because you didn't know
* what it was, but now you know what it is supposed to be.
*
* @param implicitTag The implicit tag for the encoding.
* @param template The template to use to decode this ANY.
* @return The output of the given template when it is fed the
* encoding of this ANY.
*/
public ASN1Value decodeWith(Tag implicitTag, ASN1Template template)
throws IOException, InvalidBERException
{
ByteArrayInputStream bis = new ByteArrayInputStream(encoded);
return template.decode(implicitTag, bis);
}
/**
* @param implicitTag This parameter is ignored, because
* ANY values cannot have implicit tags.
*/
public void encode(Tag implicitTag, OutputStream ostream)
throws IOException
{
if( ! implicitTag.equals(tag) ) {
Assert.notReached("No implicit tags allowed for ANY");
}
ostream.write(encoded);
}
/**
* Extracts the contents from the ANY and encodes them with
* the provided tag.
*/
public void encodeWithAlternateTag(Tag alternateTag, OutputStream ostream)
throws IOException, InvalidBERException
{
byte[] contents = getContents();
ASN1Header oldHead = getHeader();
Assert._assert( contents.length == oldHead.getContentLength() );
ASN1Header newHead = new ASN1Header( alternateTag, oldHead.getForm(),
contents.length);
newHead.encode(ostream);
ostream.write(contents);
}
/**
* Returns a singleton instance of a decoding template.
*/
public static Template getTemplate() {
return templateInstance;
}
private static Template templateInstance = new Template();
/**
* A class for decoding ANY
values from BER.
*/
public static class Template implements ASN1Template {
public boolean tagMatch(Tag tag) {
return true; // wheeeeee...it's ANY!
}
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
try {
ASN1Header head = ASN1Header.lookAhead(istream);
if( head.getContentLength() == -1 ) {
// indefinite length encoding
ByteArrayOutputStream recording = new ByteArrayOutputStream();
// eat the header off the input stream
head = new ASN1Header(istream);
// write the header to the recording stream
recording.write( head.encode() );
// write all objects from the input stream to the recording
// stream, until we hit an END-OF-CONTENTS tag
ANY any;
ANY.Template anyt = new ANY.Template();
int count=0;
do {
any = (ANY) anyt.decode(istream);
recording.write( any.getEncoded() );
} while( ! any.getTag().equals(Tag.EOC) );
return new ANY( head.getTag(), recording.toByteArray() );
} else {
// definite length encoding
byte[] data = new byte[ (int) head.getTotalLength() ];
ASN1Util.readFully(data, istream);
return new ANY(head.getTag(), data);
}
} catch( InvalidBERException e ) {
throw new InvalidBERException(e, "ANY");
}
}
public ASN1Value decode(Tag implicitTag, InputStream istream)
throws IOException, InvalidBERException
{
throw new InvalidBERException("Implicit tag on ANY");
}
} // End of Template
}
jss-4.4.3/jss/org/mozilla/jss/asn1/ASN1Header.java 0000664 0000000 0000000 00000027441 13261450000 0021474 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.math.BigInteger;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.util.Vector;
import org.mozilla.jss.util.Assert;
/**
* The portion of a BER encoding that precedes the contents octets. Consists
* of the tag, form, and length octets.
*/
public class ASN1Header {
// This is set by the the decoding constructor, and by the encode()
// method. If it is set by the decoding constructor, it is supposed
// to represent what was actually read from the input stream, so it
// must not be overwritten later by the output of encode(), which could
// be a different encoding (DER vs. BER, for example).
private byte[] cachedEncoding = null;
/**
* Returns the length of the header plus the length of the contents;
* the total length of the DER encoding of an ASN1 value. Returns
* -1 if indefinite length encoding was used.
*/
public long getTotalLength() {
if( contentLength == -1 ) {
return -1;
} else {
return encode().length + contentLength;
}
}
private Tag tag;
public Tag getTag() {
return tag;
}
// -1 means indefinite length encoding
private long contentLength;
/**
* Returns -1 for indefinite length encoding.
*/
public long getContentLength() {
return contentLength;
}
// PRIMITIVE or CONSTRUCTED
public static final Form PRIMITIVE = Form.PRIMITIVE;
public static final Form CONSTRUCTED = Form.CONSTRUCTED;
private Form form;
/**
* Returns the Form, PRIMITIVE or CONSTRUCTED.
*/
public Form getForm() {
return form;
}
// This is the maximum size of ASN1 Header we support.
// 32 bytes is pretty huge, I've never seen anything bigger than 7.
private static final int MAX_LOOK_AHEAD = 32;
/**
* Returns information about the next item in the stream, but does not
* consume any octets.
* @exception IOException If the input stream does not support look ahead.
*/
public static ASN1Header lookAhead(InputStream derStream)
throws IOException, InvalidBERException
{
if( ! derStream.markSupported() ) {
throw new IOException("Mark not supported on this input stream");
}
derStream.mark(MAX_LOOK_AHEAD);
ASN1Header info = new ASN1Header(derStream);
derStream.reset();
return info;
}
/**
* Gets info about the next item in the DER stream, consuming the
* identifier and length octets.
*/
public ASN1Header(InputStream istream)
throws InvalidBERException, IOException
{
// default BAOS size is 32 bytes, which is plenty
ByteArrayOutputStream encoding = new ByteArrayOutputStream();
int inInt = istream.read();
if( inInt == -1 ) {
throw new InvalidBERException("End-of-file reached while "+
"decoding ASN.1 header");
}
encoding.write(inInt);
byte byte1 = (byte) inInt;
Tag.Class tagClass;
//
// Get Tag Class
//
tagClass = Tag.Class.fromInt( (byte1 & 0xff) >>> 6 );
//
// Get form
//
if( (byte1 & 0x20) == 0x20 ) {
form = CONSTRUCTED;
} else {
form = PRIMITIVE;
}
//
// Get Tag Number
//
long tagNum;
if( (byte1 & 0x1f) == 0x1f ) {
// long form
//
// read all octets into a Vector of Bytes
//
byte next;
Vector bV = new Vector();
// last byte has MSB == 0.
do {
inInt = istream.read();
if( inInt == -1 ) {
throw new InvalidBERException("End-of-file reached while"
+" decoding ASN.1 header");
}
encoding.write(inInt);
next = (byte) inInt;
bV.addElement( new Byte(next) );
} while( (next & 0x80) == 0x80 );
Assert._assert( bV.size() > 0 );
//
// Copy Vector of 7-bit bytes into array of 8-bit bytes.
//
byte[] bA = new byte[ ( (bV.size()*7) + 7 ) / 8 ];
int v; // vector index
int a; // array index
// clear the target array
for( a = 0; a < bA.length; a++ ) {
bA[a] = 0;
}
int shift = 0; // the amount the Vector is shifted from the array
// copy bits from the Vector to the array, going from the
// end (LSB) to the beginning (MSB).
a = bA.length - 1;
for( v=bV.size()-1 ; v >= 0; v--) {
Assert._assert( v >= 0 );
Assert._assert( v < bV.size() );
Assert._assert( a >= 0 );
Assert._assert( a < bA.length );
// MSB is not part of the number
byte b = (byte) ( ((Byte)bV.elementAt(v)).byteValue() & 0x7f );
bA[a] |= b << shift;
if( shift > 1 ) {
// The byte from the Vector falls across a byte boundary
// in the array. We've already got the less-significant
// bits, now copy the more-significant bits into
// the next element of the array.
Assert._assert( a > 0 );
--a;
bA[a] |= b >>> (8-shift);
}
shift = (shift+7)%8; // update shift
}
// Create a new unsigned BigInteger from the byte array
tagNum = (new BigInteger( 1, bA )).longValue();
} else {
// short form
tagNum = byte1 & 0x1f;
}
tag = new Tag(tagClass, tagNum);
//
// Get Length
//
inInt = istream.read();
if(inInt == -1) {
throw new InvalidBERException("End-of-file reached while "+
"decoding ASN.1 header");
}
encoding.write(inInt);
byte lenByte = (byte) inInt;
if( (lenByte & 0x80) == 0 ) {
// short form
contentLength = lenByte;
} else {
// long form
if( (lenByte & 0x7f) == 0 ) {
// indefinite
contentLength = -1;
} else {
// definite
byte[] lenBytes = new byte[ lenByte & 0x7f ];
ASN1Util.readFully(lenBytes, istream);
encoding.write( lenBytes );
contentLength = (new BigInteger( 1, lenBytes )).longValue();
}
}
// save our encoding so we don't have to recompute it later
cachedEncoding = encoding.toByteArray();
}
/**
* This constructor is to be called when we are constructing an ASN1Value
* rather than decoding it.
* @param contentLength Must be ≥0. Although indefinite length
* decoding is supported, indefinite length encoding
* is not.
*/
public ASN1Header( Tag tag, Form form, long contentLength)
{
this.tag = tag;
this.form = form;
Assert._assert(contentLength >= 0);
this.contentLength = contentLength;
}
public void encode( OutputStream ostream )
throws IOException
{
ostream.write( encode() );
}
public byte[] encode() {
// It's important that we not recompute the encoding if it was
// set by ASN1Header(InputStream), since in that case it represents
// the encoding that was actually read from the InputStream.
if( cachedEncoding != null ) {
return cachedEncoding;
}
ByteArrayOutputStream cache = new ByteArrayOutputStream();
//
// Identifier octet(s)
//
byte idOctet = 0;
idOctet |= tag.getTagClass().toInt() << 6;
if( form == CONSTRUCTED ) {
idOctet |= 0x20;
}
if( tag.getNum() <= 30 ) {
// short form
idOctet |= (tag.getNum() & 0x1f );
cache.write( idOctet );
} else {
// long form
idOctet |= 0x1f;
BigInteger tagNum = BigInteger.valueOf(tag.getNum());
cache.write( idOctet );
int bitlength = tagNum.bitLength();
int reps = (bitlength+6)/7;
for( reps = reps-1; reps > 0 ; reps--) {
long shifted = tag.getNum() >>> ( 7*reps );
cache.write( (((byte)shifted) & 0x7f) | 0x80 );
}
cache.write( ((byte)tag.getNum()) & 0x7f );
}
//
// Length Octets
//
if( contentLength == -1 ) {
// indefinite form
cache.write( (byte) 0x80 );
} else if( contentLength <= 127 ) {
// short form
cache.write( (byte) contentLength );
} else {
// long form
byte[] val = unsignedBigIntToByteArray(
BigInteger.valueOf(contentLength) );
cache.write( ((byte)val.length) | 0x80 );
cache.write( val, 0, val.length );
}
cachedEncoding = cache.toByteArray();
return cachedEncoding;
}
/**
* Converts an unsigned BigInteger to a minimal-length byte array.
* This is necessary because BigInteger.toByteArray() attaches an extra
* sign bit, which could cause the size of the byte representation to
* be bumped up by an extra byte.
*/
public static byte[] unsignedBigIntToByteArray(BigInteger bi) {
// make sure it is not negative
Assert._assert( bi.compareTo(BigInteger.valueOf(0)) != -1 );
// find minimal number of bytes to hold this value
int bitlen = bi.bitLength(); // minimal number of bits, without sign
int bytelen;
if( bitlen == 0 ) {
// special case, since bitLength() returns 0
bytelen = 1;
} else {
bytelen = (bitlen + 7) / 8;
}
byte[] withSign = bi.toByteArray();
if( bytelen == withSign.length ) {
return withSign;
} else {
// trim off extra byte at the beginning
Assert._assert( bytelen == withSign.length - 1 );
Assert._assert( withSign[0] == 0 );
byte[] without = new byte[bytelen];
System.arraycopy(withSign,1, without, 0, bytelen);
return without;
}
}
/**
* Verifies that this header has the given tag and form.
* @exception InvalidBERException If the header's tag or form
* differ from those passed in.
*/
public void validate(Tag expectedTag, Form expectedForm)
throws InvalidBERException
{
validate(expectedTag);
if( getForm() != expectedForm ) {
throw new InvalidBERException("Incorrect form: expected ["+
expectedForm+"], found ["+getForm());
}
}
/**
* Verifies that this head has the given tag.
* @exception InvalidBERException If the header's tag differs from that
* passed in.
*/
public void validate(Tag expectedTag) throws InvalidBERException {
if( ! getTag().equals( expectedTag ) ) {
throw new InvalidBERException("Incorrect tag: expected ["+
expectedTag+"], found ["+getTag()+"]");
}
}
/**
* Returns true
if this is a BER end-of-contents marker.
*/
public boolean isEOC() {
return( tag.equals(Tag.EOC) );
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/ASN1Template.java 0000664 0000000 0000000 00000003074 13261450000 0022053 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.IOException;
/**
* An interface for decoding ASN1Values from their BER encodings.
*
* @see ASN1Value
*/
public interface ASN1Template {
/**
* Determines whether the given tag will satisfy this template.
*/
public boolean tagMatch(Tag tag);
/**
* Decodes an ASN1Value from the InputStream without an implicit tag.
* @param istream Must support marking (markSupported() == true).
* For example, ByteArrayInputStream and BufferedInputStream
* support marking, but FileInputStream does not. If your source
* does not support marking, you can wrap it in a
* BufferedInputStream.
*/
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException;
/**
* Decodes an ASN1Value from the InputStream with the given implicit
* tag.
* @param istream Must support marking (markSupported() == true).
* For example, ByteArrayInputStream and BufferedInputStream
* support marking, but FileInputStream does not. If your source
* does not support marking, you can wrap it in a
* BufferedInputStream.
*/
public ASN1Value decode(Tag implicitTag, InputStream istream)
throws IOException, InvalidBERException;
}
jss-4.4.3/jss/org/mozilla/jss/asn1/ASN1Util.c 0000664 0000000 0000000 00000007123 13261450000 0020515 0 ustar 00root root 0000000 0000000 /* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Netscape Security Services for Java.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "_jni/org_mozilla_jss_asn1_ASN1Util.h"
#include BIT STRING
, which is an ordered sequence of bits.
* The bits are stored the same way they are encoded in BER: as an array
* of bytes with 0-7 unused bits at the end.
*/
public class BIT_STRING implements ASN1Value {
private BIT_STRING() { }
private byte[] bits;
private int padCount;
private boolean removeTrailingZeroes = false;
/**
* @param bits The bits packed into an array of bytes, with padding
* at the end. The array may be empty (but not null), in which case
* padCount
must be zero. The array is referenced,
* not cloned.
* @param padCount The number of padding bits at the end of the array.
* Must be in the range [0,7]
.
* @exception NumberFormatException If padCount
is not in
* the range [0,7]
, or bits
is
* empty and padCount
is non-zero.
*/
public BIT_STRING(byte[] bits, int padCount)
throws NumberFormatException
{
if(padCount < 0 || padCount > 7) {
throw new NumberFormatException();
}
if(bits.length == 0 && padCount != 0) {
throw new NumberFormatException();
}
this.bits = bits;
this.padCount = padCount;
}
/**
* Constructs a BIT_STRING from a BitSet.
* @param bs A BitSet.
* @param numBits The number of bits to copy from the BitSet.
* This is necessary because the size of a BitSet is always padded
* up to a multiple of 64, but not all of these bits may
* be significant.
* @exception NumberFormatException If numBits
is larger
* than bs.size()
or less than zero.
*/
public BIT_STRING(BitSet bs, int numBits)
throws NumberFormatException
{
if( numBits < 0 || numBits > bs.size() ) {
throw new NumberFormatException();
}
// allocate enough bytes to hold all the bits
bits = new byte[(numBits+7) / 8];
padCount = (bits.length * 8) - numBits;
Assert._assert( padCount >= 0 && padCount <= 7);
for(int i=0; i < numBits; i++) {
if( bs.get(i) ) {
bits[i/8] |= 0x80 >>> (i%8);
}
}
}
/**
* Determines whether the DER-encoding of this bitstring will have
* its trailing zeroes removed. Generally, DER requires that trailing
* zeroes be removed when the bitstring is used to hold flags, but
* not when it is used to hold binary data (such as a public key).
* The default is false.
*/
public boolean getRemoveTrailingZeroes() {
return this.removeTrailingZeroes;
}
/**
* Determines whether the DER-encoding of this bitstring will have
* its trailing zeroes removed. Generally, DER requires that trailing
* zeroes be removed when the bitstring is used to hold flags, but
* not when it is used to hold binary data (such as a public key).
* The default is false. If this bit string is used to hold
* flags, you should set this to true.
*/
public void setRemoveTrailingZeroes(boolean removeTrailingZeroes) {
this.removeTrailingZeroes = removeTrailingZeroes;
}
/**
* Returns the bits packed into an array of bytes, with padding
* at the end. The array may be empty (but not null), in which case
* padCount
must be zero. The array is referenced,
* not cloned.
*/
public byte[] getBits() {
return bits;
}
/**
* Copies this BIT STRING into a Java BitSet. Note that BitSet.size()
* will not accurately reflect the number of bits in the BIT STRING,
* because the size of a BitSet is always rounded up to the next multiple
* of 64. The extra bits will be set to 0.
*/
public BitSet toBitSet() {
BitSet bs = new BitSet();
int numBits = (bits.length * 8) - padCount;
for( int i=0; i < numBits; i++) {
if( (bits[i/8] & (0x80 >>> (i%8))) != 0 ) {
bs.set(i);
} else {
bs.clear(i);
}
}
return bs;
}
/**
* Copies this BIT STRING into a boolean array. Each element of the array
* represents one bit with true
for 1 and false
* for 0.
*/
public boolean[] toBooleanArray() {
boolean[] array = new boolean[(bits.length*8) - padCount];
// all elements are set to false by default
for(int i=0; i < array.length; i++) {
if( (bits[i/8] & (0x80 >>> (i%8))) != 0 ) {
array[i] = true;
}
}
return array;
}
/**
* Returns the number of padding bits at the end of the array.
* Must be in the range [0,7]
.
*/
public int getPadCount() {
return padCount;
}
public static final Tag TAG = new Tag(Tag.UNIVERSAL, 3);
public static final Form FORM = Form.PRIMITIVE;
public Tag getTag() {
return TAG;
}
public void encode(OutputStream ostream) throws IOException {
encode(TAG, ostream);
}
public void encode(Tag implicitTag, OutputStream ostream)
throws IOException
{
// force all unused bits to be zero, in support of DER standard.
if( bits.length > 0 ) {
bits[bits.length-1] &= (0xff << padCount);
}
int padBits;
int numBytes;
if( removeTrailingZeroes ) {
// first pare off empty bytes
numBytes = bits.length;
for( ; numBytes > 0; --numBytes) {
if( bits[numBytes-1] != 0 ) {
break;
}
}
// Now compute the number of unused bits. This includes any
// trailing zeroes, whether they are significant or not.
if( numBytes == 0 ) {
padBits = 0;
} else {
for( padBits=0; padBits < 8; ++padBits ) {
if( (bits[numBytes-1] & (1 << padBits)) != 0 ) {
break;
}
}
Assert._assert(padBits >=0 && padBits <= 7);
}
} else {
// Don't remove trailing zeroes. Just write the bits out as-is.
padBits = padCount;
numBytes = bits.length;
}
ASN1Header head = new ASN1Header(implicitTag, FORM, numBytes+1);
head.encode(ostream);
ostream.write(padBits);
ostream.write(bits, 0, numBytes);
}
private static final Template templateInstance = new Template();
public static Template getTemplate() {
return templateInstance;
}
/**
* A class for decoding a BIT_STRING
from its BER encoding.
*/
public static class Template implements ASN1Template {
public boolean tagMatch(Tag tag) {
return( TAG.equals(tag) );
}
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
return decode(TAG, istream);
}
public ASN1Value decode(Tag implicitTag, InputStream istream)
throws IOException, InvalidBERException
{
try {
ASN1Header head = new ASN1Header( istream );
head.validate( implicitTag );
if( head.getContentLength() == -1 ) {
// indefinite length encoding
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int padCount=0;
ASN1Header ahead;
do {
ahead = ASN1Header.lookAhead(istream);
if( ! ahead.isEOC() ) {
if(padCount != 0 ) {
throw new InvalidBERException("Element of constructed "+
"BIT STRING has nonzero unused bits, but is not\n"+
"the last element of the construction.");
}
BIT_STRING.Template bst = new BIT_STRING.Template();
BIT_STRING bs = (BIT_STRING) bst.decode(istream);
bos.write( bs.getBits() );
padCount = bs.getPadCount();
}
} while( ! ahead.isEOC() );
// consume the EOC
ahead = new ASN1Header(istream);
return new BIT_STRING( bos.toByteArray(), padCount );
}
// First octet is the number of unused bits in last octet
int padCount = istream.read();
if( padCount == -1 ) {
throw new InvalidBERException.EOF();
} else if( padCount < 0 || padCount > 7 ) {
throw new InvalidBERException("Unused bits not in range [0,7]");
}
// get the rest of the octets
byte[] bits = new byte[ (int) head.getContentLength() - 1];
ASN1Util.readFully(bits, istream);
return new BIT_STRING(bits, padCount);
} catch(InvalidBERException e) {
throw new InvalidBERException(e, "BIT STRING");
}
}
} // end of Template
}
jss-4.4.3/jss/org/mozilla/jss/asn1/BMPString.java 0000664 0000000 0000000 00000006334 13261450000 0021464 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.CharConversionException;
import java.io.UnsupportedEncodingException;
import org.mozilla.jss.util.Assert;
/**
* The ASN.1 type BMPString. BMPStrings use the Unicode character set.
* They are encoded and decoded in big-endian format using two octets.
*/
public class BMPString extends CharacterString implements ASN1Value {
/**
* Creates a new BMPString from an array of Java characters.
*/
public BMPString(char[] chars) throws CharConversionException {
super(chars);
}
/**
* Creates a new BMPString from a Java String.
*/
public BMPString(String s) throws CharConversionException {
super(s);
}
/**
* Returns the conversion object for converting between an encoded byte
* array an an array of Java characters.
*/
CharConverter getCharConverter() {
return converterInstance;
}
private static final BMPConverter converterInstance = new BMPConverter();
static final Tag TAG = new Tag( Tag.UNIVERSAL, 30 );
static final Form FORM = Form.PRIMITIVE;
public Tag getTag() {
return TAG;
}
/**
* Returns a singleton instance of BMPString.Template. This is more
* efficient than creating a new BMPString.Template.
*/
public static Template getTemplate() {
return templateInstance;
}
private static final Template templateInstance = new Template();
// nested class
public static class Template
extends CharacterString.Template implements ASN1Template
{
protected Tag getTag() {
return TAG;
}
public boolean tagMatch(Tag tag) {
return TAG.equals(tag);
}
protected CharConverter getCharConverter() {
return new BMPConverter();
}
protected CharacterString generateInstance(char[] chars)
throws CharConversionException
{
return new BMPString(chars);
}
protected String typeName() {
return "BMPString";
}
}
private static class BMPConverter implements CharConverter {
public char[] byteToChar(byte[] bytes, int offset, int len)
throws CharConversionException
{
try {
String s = new String(bytes, offset, len, "UnicodeBig");
return s.toCharArray();
} catch( UnsupportedEncodingException e ) {
String err = "Unable to find UnicodeBig encoding mechanism";
Assert.notReached(err);
throw new CharConversionException(err);
}
}
public byte[] charToByte(char[] chars, int offset, int len)
throws CharConversionException
{
try {
// We don't want the byte-order mark
String s = new String(chars, offset, len);
return s.getBytes("UnicodeBigUnmarked");
} catch( UnsupportedEncodingException e ) {
String err = "Unable to find UnicodeBigUnmarked encoding mechanism";
Assert.notReached(err);
throw new CharConversionException(err);
}
}
} // end of char converter
}
jss-4.4.3/jss/org/mozilla/jss/asn1/BOOLEAN.java 0000664 0000000 0000000 00000005624 13261450000 0020737 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* An ASN.1 BOOLEAN
value.
*/
public class BOOLEAN implements ASN1Value {
public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 1);
public static final Form FORM = Form.PRIMITIVE;
public Tag getTag() {
return TAG;
}
private ASN1Header getHeader() {
return getHeader(TAG);
}
private ASN1Header getHeader(Tag implicitTag) {
return new ASN1Header(implicitTag, FORM, 1 );
}
public void encode(OutputStream ostream) throws IOException {
encode(TAG, ostream);
}
public void encode(Tag implicitTag, OutputStream ostream)
throws IOException
{
getHeader(implicitTag).encode(ostream);
if( val ) {
ostream.write( 0xff );
} else {
ostream.write( 0x00 );
}
}
private BOOLEAN() { }
private boolean val;
/**
* Creates a BOOLEAN
with the given value.
*/
public BOOLEAN(boolean val) {
this.val = val;
}
/**
* Returns the boolean value of this BOOLEAN
.
*/
public boolean toBoolean() {
return val;
}
/**
* Returns "true" or "false".
*/
public String toString() {
if(val) {
return "true";
} else {
return "false";
}
}
private static final Template templateInstance = new Template();
public static Template getTemplate() {
return templateInstance;
}
/**
* A Class for decoding BOOLEAN
values from their BER
* encodings.
*/
public static class Template implements ASN1Template {
public boolean tagMatch(Tag tag) {
return( tag.equals( BOOLEAN.TAG ) );
}
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
return decode(TAG, istream);
}
public ASN1Value decode(Tag tag, InputStream istream)
throws IOException, InvalidBERException
{
try {
ASN1Header head = new ASN1Header(istream);
head.validate(tag, FORM);
int b = istream.read();
if( b == -1 ) {
throw new InvalidBERException("End-of-file reached while "+
"decoding BOOLEAN");
}
if( b == 0x00 ) {
return new BOOLEAN(false);
} else {
return new BOOLEAN(true);
}
} catch(InvalidBERException e) {
throw new InvalidBERException(e, "BOOLEAN");
}
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/CHOICE.java 0000664 0000000 0000000 00000016743 13261450000 0020616 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Vector;
import org.mozilla.jss.util.Assert;
/**
* Objects of this class are generated by CHOICE.Template.decode(). It is
* not necessary to use them to encode a CHOICE. Since the encoding of a
* CHOICE is simply the encoding of the chosen element, it is easier
* to just write out the chosen element.
*/
public class CHOICE implements ASN1Value {
private CHOICE() { }
private Tag tag;
private ASN1Value val;
/**
* Create a CHOICE whose chosen element has an implicit tag.
*/
public CHOICE(Tag implicitTag, ASN1Value val) {
tag = implicitTag;
this.val = val;
}
/**
* Create a CHOICE whose chosen element has no implicit tag.
*/
public CHOICE(ASN1Value val) {
this.tag = val.getTag();
this.val = val;
}
/**
* Returns the tag that the chosen element is encoded with, which is
* either the underlying tag of the element or an implicit tag.
*/
public Tag getTag() {
return tag;
}
/**
* Returns the chosen value.
*/
public ASN1Value getValue() {
return val;
}
public static CHOICE.Template getTemplate() {
return new CHOICE.Template();
}
/**
* Encodes this CHOICE. This merely consists of encoding the chosen
* element with an implicit tag, if one was given in the constructor,
* or with its own underlying tag.
*/
public void encode( OutputStream ostream ) throws IOException {
val.encode( tag, ostream );
}
/**
* Encodes this CHOICE. This merely consists of encoding the chosen
* element with an implicit tag, if one was given in the constructor,
* or with its own underlying tag.
*
* @param implicitTag This value is ignored. The tag of a CHOICE
* is merely the tag of the chosen element of the CHOICE. A
* CHOICE cannot itself have an implicit tag.
*/
public void encode( Tag implicitTag, OutputStream ostream )
throws IOException
{
Assert._assert(implicitTag.equals(tag));
val.encode( tag, ostream );
}
/**
* A Template for decoding ASN.1 CHOICE
s
*/
public static class Template implements ASN1Template {
// The the various possibilities in this CHOICE
private Vector templates = new Vector();
/**
* Creates an empty CHOICE template
*/
public Template() { }
/**
* Adds a new sub-template to this CHOICE template with no implicit tag.
*/
public void addElement( ASN1Template template ) {
templates.addElement( new Element( template ) );
}
/**
* Adds a new sub-template to this CHOICE template with an implicit tag.
*/
public void addElement( Tag implicitTag, ASN1Template template) {
templates.addElement( new Element( implicitTag, template) );
}
/**
* Returns the number of elements in this CHOICE template.
*/
public int size() {
return templates.size();
}
/**
* Retrieves the element at the specified index.
*/
public ASN1Template elementAt(int index) {
return ((Element)templates.elementAt(index)).getTemplate();
}
/**
* Retrieves the implicit tag of the element at the specified index.
* Returns null if there is no implicit tag for this element.
*/
public Tag implicitTagAt(int index) {
return ((Element)templates.elementAt(index)).getImplicitTag();
}
/**
* Empties this CHOICE template.
*/
public void removeAllElements() {
templates.removeAllElements();
}
/**
* Removes the element at the specified index.
*/
public void removeElementAt(int index) {
templates.removeElementAt(index);
}
/**
* Determines whether the given tag will satisfy this template.
* For a CHOICE, this is true if the tag satisfies any sub-template.
*/
public boolean tagMatch(Tag t) {
int size = size();
for(int i = 0; i < size; i++) {
Tag impl = implicitTagAt(i);
if( impl != null ) {
// There is an implicit tag, if we match it we have a match
if( impl.equals(t) ) {
return true;
}
} else {
// no implicit tag, look at the sub-template itself
ASN1Template templ = elementAt(i);
if( templ.tagMatch(t) ) {
return true;
}
}
}
// none of the elements matched
return false;
}
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
ASN1Header head = ASN1Header.lookAhead(istream);
Tag tag = head.getTag();
// Loop over all the elements of the CHOICE template until we
// find one with a matching tag.
int size = size();
for(int i=0; i < size; i++) {
if( implicitTagAt(i) != null ) {
if( implicitTagAt(i).equals(tag) ) {
// match by implicit tag!
ASN1Value val = elementAt(i).decode( implicitTagAt(i),
istream );
//return elementAt(i).decode( implicitTagAt(i), istream );
return new CHOICE( implicitTagAt(i), val );
}
} else {
if( elementAt(i).tagMatch(tag) ) {
// match by base tag !
//return elementAt(i).decode(istream);
return new CHOICE( elementAt(i).decode(istream) );
}
}
}
// we didn't find any match
throw new InvalidBERException("Unable to decode CHOICE");
}
// Implicit tags are illegal for CHOICE (and ANY)
/**
* Decodes a CHOICE.
* @param implicitTag This parameter is ignored. A choice
* cannot have an implicit tag.
*/
public ASN1Value decode(Tag implicitTag, InputStream istream)
throws IOException, InvalidBERException
{
return decode(istream);
}
/**
* An element in a CHOICE template, consisting of a nested template
* and, optionally, an implicit tag for that template.
*/
private static class Element {
private ASN1Template template;
private Tag implicitTag=null;
/**
* Creates a CHOICE template element with no implicit tag.
*/
public Element(ASN1Template template) {
this.template = template;
}
/**
* Creates a CHOICE template element with an implicit tag.
*/
public Element(Tag implicitTag, ASN1Template template) {
this.template = template;
this.implicitTag = implicitTag;
}
/**
* Returns the template of this CHOICE template element.
*/
public ASN1Template getTemplate() {
return template;
}
/**
* Returns the implicit tag for this CHOICE template element,
* if there is one. If not, returns null.
*/
public Tag getImplicitTag() {
return implicitTag;
}
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/CharConverter.java 0000664 0000000 0000000 00000000770 13261450000 0022422 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.CharConversionException;
interface CharConverter {
public char[] byteToChar(byte[] bytes, int offset, int len)
throws CharConversionException;
public byte[] charToByte(char[] chars, int offset, int len)
throws CharConversionException;
}
jss-4.4.3/jss/org/mozilla/jss/asn1/CharacterString.java 0000664 0000000 0000000 00000010541 13261450000 0022735 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.CharConversionException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
/**
* An abstract base class for all character string types in ASN.1.
*/
public abstract class CharacterString implements ASN1Value {
abstract CharConverter getCharConverter();
public abstract Tag getTag();
static final Form FORM = Form.PRIMITIVE;
private char[] chars;
/**
* Converts this ASN.1 character string to a Java String.
*/
public String toString() {
return new String(chars);
}
/**
* Converts this ASN.1 character string to an array of Java characters.
*/
public char[] toCharArray() {
return chars;
}
protected CharacterString(char[] chars) throws CharConversionException {
this.chars = chars;
cachedContents = computeContents();
}
protected CharacterString(String s) throws CharConversionException {
this.chars = s.toCharArray();
cachedContents = computeContents();
}
private byte[] cachedContents;
private byte[] getEncodedContents() {
return cachedContents;
}
private byte[] computeContents() throws CharConversionException {
CharConverter converter = getCharConverter();
byte[] contents = converter.charToByte(chars, 0, chars.length);
return contents;
}
public void encode(OutputStream ostream) throws IOException {
encode( getTag(), ostream );
}
public void encode( Tag implicitTag, OutputStream ostream )
throws IOException
{
byte[] contents = getEncodedContents();
ASN1Header head = new ASN1Header( implicitTag, FORM, contents.length);
head.encode(ostream);
ostream.write( contents );
}
public abstract static class Template implements ASN1Template {
/**
* Must be overridden to return the tag for the subclass.
*/
protected abstract Tag getTag();
public abstract boolean tagMatch(Tag tag);
/**
* Must be overridden to return the correct character converter
* for the subclass.
*/
protected abstract CharConverter getCharConverter();
/**
* Must be overridden to create an instance of the subclass given
* a char array.
*/
protected abstract CharacterString generateInstance(char[] chars)
throws CharConversionException;
/**
* Must be overridden to provide the name of the subclass, for including
* into error messages.
*/
protected abstract String typeName();
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
return decode(getTag(), istream);
}
public ASN1Value decode(Tag implicitTag, InputStream istream)
throws IOException, InvalidBERException
{
try {
ASN1Header head = new ASN1Header(istream);
head.validate(implicitTag);
byte[] raw; // raw bytes, not translated to chars yet
if( head.getContentLength() == -1 ) {
// indefinite length encoding
ASN1Header ahead;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
do {
ahead = ASN1Header.lookAhead( istream );
if( ! ahead.isEOC() ) {
OCTET_STRING.Template ot = new OCTET_STRING.Template();
OCTET_STRING os = (OCTET_STRING) ot.decode(istream);
bos.write( os.toByteArray() );
}
} while( ! ahead.isEOC() );
// consume EOC
ahead = new ASN1Header(istream);
raw = bos.toByteArray();
} else {
// definite length
raw = new byte[ (int) head.getContentLength() ];
ASN1Util.readFully(raw, istream);
}
char[] chars = getCharConverter().byteToChar(raw, 0, raw.length);
return generateInstance(chars);
} catch( CharConversionException e ) {
throw new InvalidBERException(e.getMessage());
} catch( InvalidBERException e ) {
throw new InvalidBERException(e, typeName());
}
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/CountingStream.java 0000664 0000000 0000000 00000005174 13261450000 0022622 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.*;
/**
* This class keeps track of the number of bytes that have been read from
* a stream. It will be incremented by the number of bytes read or skipped.
* If the stream is marked and then reset, the number of bytes read will
* be reset as well.
*/
class CountingStream extends InputStream {
private int count=0;
private int markpos;
private InputStream source;
private static final boolean DEBUG = false;
private CountingStream() { }
public CountingStream(InputStream source) {
this.source = source;
}
public int available() throws IOException {
return source.available();
}
public void mark(int readlimit) {
source.mark(readlimit);
markpos = count;
if(DEBUG) {
System.out.println("Marked at position "+markpos);
}
}
public boolean markSupported() {
return source.markSupported();
}
public int read() throws IOException {
int n = source.read();
if( n != -1 ) {
count++;
if(DEBUG) {
System.out.println("read() 1 byte, count="+count);
}
}
return n;
}
public int read(byte[] buffer) throws IOException {
int n = source.read(buffer);
if( n != -1 ) {
count += n;
}
if(DEBUG) {
System.out.println("read([]) "+n+" bytes, count="+count);
}
return n;
}
public int read(byte[] buffer, int offset, int count) throws IOException {
int n = source.read(buffer, offset, count);
if( n != -1 ) {
this.count += n;
}
if(DEBUG) {
System.out.println("read(...) "+n+" bytes, count="+this.count);
}
return n;
}
public void reset() throws IOException {
source.reset();
if(DEBUG) {
System.out.println("reset from "+count+" to "+markpos);
}
count = markpos;
}
public long skip(long count) throws IOException {
this.count += count;
if(DEBUG) {
System.out.println("skipped "+count+", now at "+this.count);
}
return source.skip(count);
}
public int getNumRead() {
return count;
}
public void resetNumRead() {
count = 0;
markpos = 0;
if(DEBUG) {
System.out.println("resetting count to 0");
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/ENUMERATED.java 0000664 0000000 0000000 00000004315 13261450000 0021305 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.IOException;
import java.io.InputStream;
/**
* Represents an ASN.1 ENUMERATED
value. This has the same
* interface as INTEGER
*/
public class ENUMERATED extends INTEGER implements ASN1Value {
public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 10);
public Tag getTag() {
return TAG;
}
/**
* Creates a new ENUMERATED value from a long.
*/
public ENUMERATED( long val ) {
super( val );
}
ENUMERATED( byte[] valBytes ) {
super( valBytes );
}
/**
* Returns the value as a long.
*/
public long getValue() {
return longValue();
}
private static final ENUMERATED.Template templateInstance =
new ENUMERATED.Template();
public static ASN1Template getTemplate() {
return templateInstance;
}
/**
* A template for decoding ENUMERATED values from their BER encodings.
* The template reads the value as an INTEGER. It does not check that it
* is a valid value for the ENUMERATED type.
*/
public static class Template
extends INTEGER.Template implements ASN1Template
{
Tag getTag() {
return ENUMERATED.TAG;
}
public boolean tagMatch(Tag tag) {
return( tag.equals(ENUMERATED.TAG) );
}
public ASN1Value
decode(Tag tag, InputStream derStream)
throws InvalidBERException, IOException
{
try {
ASN1Header wrapper = new ASN1Header(derStream);
wrapper.validate(tag, FORM);
// Is length < 1 ?
if( wrapper.getContentLength() < 1 ) {
throw new InvalidBERException("Invalid 0 length for ENUMERATED");
}
byte[] valBytes = new byte[ (int) wrapper.getContentLength() ];
ASN1Util.readFully(valBytes, derStream);
return new ENUMERATED( valBytes );
} catch(InvalidBERException e) {
throw new InvalidBERException(e, "ENUMERATED");
}
}
} // end of Template
}
jss-4.4.3/jss/org/mozilla/jss/asn1/EXPLICIT.java 0000664 0000000 0000000 00000007514 13261450000 0021101 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import org.mozilla.jss.util.Assert;
/**
* An explicit tag.
*/
public class EXPLICIT implements ASN1Value {
public static final Form FORM = Form.CONSTRUCTED;
private ASN1Value content;
private Tag tag;
private EXPLICIT() { }
/**
* Creates an EXPLICIT tag wrapping some other ASN1Value. For example,
* for the following ASN.1 snippet:
*
* MyType [3] EXPLICIT INTEGER
*
* assuming a sample value of 5 for the INTEGER, a MyType could be
* created with:
*
* EXPLICIT myValue = new EXPLICIT( new Tag(3), new INTEGER(5) );
*
*/
public EXPLICIT( Tag tag, ASN1Value content ) {
Assert._assert(tag!=null && content!=null);
this.content = content;
this.tag = tag;
}
/**
* Returns the ASN1Value that is wrapped by this EXPLICIT tag.
*/
public ASN1Value getContent() {
return content;
}
/**
* Returns the Tag of this EXPLICIT tag.
*/
public Tag getTag() {
return tag;
}
public void encode(OutputStream ostream) throws IOException {
encode(tag, ostream);
}
public void encode(Tag implicitTag, OutputStream ostream)
throws IOException
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
content.encode(bos);
byte[] contentBytes = bos.toByteArray();
ASN1Header head = new ASN1Header(implicitTag, FORM,
contentBytes.length );
head.encode(ostream);
ostream.write(contentBytes);
}
public static Template getTemplate( Tag tag, ASN1Template content) {
return new Template(tag, content);
}
/**
* A template for decoding an object wrapped in an EXPLICIT tag.
*/
public static class Template implements ASN1Template {
private ASN1Template content;
private Tag tag;
private Template() { }
/**
* Creates a template for unwrapping an object wrapped in an explicit tag.
* For example, to decode:
*
* MyValue ::= [3] EXPLICIT INTEGER
*
* use:
*
* EXPLICIT.Template myTemplate = new EXPLICIT.Template( new Tag(3),
* new INTEGER.Template() );
*
*
* @param tag The tag value of the EXPLICIT tag.
* @param content The template for decoding the object that is wrapped
* in the explicit tag.
*/
public Template(Tag tag, ASN1Template content) {
this.content = content;
this.tag = tag;
}
public boolean tagMatch(Tag tag) {
return( this.tag.equals(tag) );
}
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
return decode(tag, istream);
}
public ASN1Value decode(Tag implicitTag, InputStream istream)
throws IOException, InvalidBERException
{
try {
ASN1Header head = new ASN1Header(istream);
head.validate( implicitTag, FORM.CONSTRUCTED );
ASN1Value val = content.decode(istream);
EXPLICIT e = new EXPLICIT(tag, val);
// if indefinite content length, consume the end-of-content marker
if( head.getContentLength() == -1 ) {
head = new ASN1Header(istream);
if( ! head.isEOC() ) {
throw new InvalidBERException("No end-of-contents marker");
}
}
return e;
} catch(InvalidBERException e) {
throw new InvalidBERException(e, "EXPLICIT");
}
}
} // end of Template
}
jss-4.4.3/jss/org/mozilla/jss/asn1/FieldNotPresentException.java 0000664 0000000 0000000 00000001005 13261450000 0024571 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
/**
* An exception thrown when an optional field is not present.
*/
public class FieldNotPresentException extends java.lang.Exception
{
public FieldNotPresentException() {
super();
}
public FieldNotPresentException(String msg) {
super(msg);
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/Form.java 0000664 0000000 0000000 00000001260 13261450000 0020553 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
/**
* An enumerated type representing the forms of an ASN.1 value.
* The possibilities are PRIMITIVE and CONSTRUCTED.
*/
public class Form {
private String name;
private Form() { }
private Form(String name) {
this.name = name;
}
public static final Form PRIMITIVE = new Form("PRIMITIVE");
public static final Form CONSTRUCTED = new Form("CONSTRUCTED");
public String toString() {
return name;
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/GeneralizedTime.java 0000664 0000000 0000000 00000003143 13261450000 0022722 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import org.mozilla.jss.util.Assert;
/**
* The ASN.1 type GeneralizedTime
*/
public class GeneralizedTime extends TimeBase implements ASN1Value {
public static final Tag TAG = new Tag(Tag.UNIVERSAL, 24);
public Tag getTag() {
return TAG;
}
/**
* Creates a GeneralizedTime
from a Date.
*/
public GeneralizedTime(Date date) {
super(date);
}
protected boolean isUTC() {
return false;
}
private static final GeneralizedTime.Template templateInstance =
new GeneralizedTime.Template();
public static GeneralizedTime.Template getTemplate() {
return templateInstance;
}
/**
* A class for decoding GeneralizedTime
s.
*/
public static class Template extends TimeBase.Template
implements ASN1Template
{
protected Tag getTag() {
return TAG;
}
public boolean tagMatch(Tag tag) {
return TAG.equals(tag);
}
protected boolean isUTC() {
return false;
}
protected TimeBase generateInstance(Date date) {
return new GeneralizedTime(date);
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/IA5String.java 0000664 0000000 0000000 00000005007 13261450000 0021420 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.CharConversionException;
public class IA5String extends CharacterString implements ASN1Value {
public IA5String(char[] chars) throws CharConversionException {
super(chars);
}
public IA5String(String s) throws CharConversionException {
super(s);
}
CharConverter getCharConverter() {
return new IA5Converter();
}
public static final Tag TAG = new Tag( Tag.Class.UNIVERSAL, 22 );
public Tag getTag() {
return TAG;
}
public static Template getTemplate() {
return templateInstance;
}
private static final Template templateInstance = new Template();
// nested class
public static class Template
extends CharacterString.Template implements ASN1Template
{
public Tag getTag() {
return IA5String.TAG;
}
public boolean tagMatch(Tag tag) {
return( tag.equals( IA5String.TAG ));
}
protected CharConverter getCharConverter() {
return new IA5Converter();
}
protected CharacterString generateInstance(char[] chars)
throws CharConversionException
{
return new IA5String(chars);
}
protected String typeName() {
return "IA5String";
}
}
// nested class
private static class IA5Converter implements CharConverter {
public char[] byteToChar(byte[] bytes, int offset, int len)
throws CharConversionException
{
char[] chars = new char[len];
int c; // char index
int b; // byte index
for(b = offset, c=0; c < len; b++, c++) {
if( (bytes[b] & 0x80) != 0 ) {
throw new CharConversionException("Invalid character: "+
bytes[b]);
}
chars[c] = (char) (bytes[b] & 0x7f);
}
return chars;
}
public byte[] charToByte(char[] chars, int offset, int len)
throws CharConversionException
{
byte[] bytes = new byte[len];
int c; // char index
int b; // byte index
for(c = offset, b = 0; b < len; c++, b++) {
if( (chars[c] & 0x7f) != chars[c] ) {
throw new CharConversionException("Invalid character: "+
chars[c]);
}
bytes[b] = (byte) (chars[c] & 0x7f);
}
return bytes;
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/INTEGER.java 0000664 0000000 0000000 00000014172 13261450000 0020753 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.util.Random;
/**
* The ASN.1 type INTEGER
. This class extends BigInteger.
*/
public class INTEGER extends BigInteger implements ASN1Value {
private byte[] encodedContents = null;
private byte[] getEncodedContents() {
if( encodedContents == null ) {
encodedContents = toByteArray();
}
return encodedContents;
}
private ASN1Header getHeader(Tag t) {
return new ASN1Header( t, FORM, getContentLength() );
}
public INTEGER(String s) throws NumberFormatException {
super(s);
}
public INTEGER(String s, int r) throws NumberFormatException {
super(s, r);
}
public INTEGER(byte[] bval) throws NumberFormatException {
super(bval);
}
public INTEGER(int sign, byte[] mag) throws NumberFormatException {
super(sign, mag);
}
public INTEGER(int numBits, Random rnd) throws NumberFormatException {
super(numBits, rnd);
}
public INTEGER(int bitLength, int certainty, Random rnd) {
super(bitLength, certainty, rnd);
}
public INTEGER(long val) {
super( BigInteger.valueOf(val).toByteArray() );
}
public INTEGER(BigInteger bi) {
super( bi.toByteArray() );
}
public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 2);
public Tag getTag() {
return TAG;
}
public static final Form FORM = Form.PRIMITIVE;
public void encode(OutputStream outStream) throws IOException {
encode(getTag(), outStream);
}
public void encode(Tag implicitTag, OutputStream outStream)
throws IOException
{
// write header
getHeader(implicitTag).encode( outStream );
// write contents
outStream.write( getEncodedContents() );
}
public long getContentLength() {
return getEncodedContents().length;
}
public byte[] encode() throws IOException {
ByteArrayOutputStream b = new ByteArrayOutputStream();
encode(b);
return b.toByteArray();
}
private static final INTEGER.Template templateInstance =
new INTEGER.Template();
public static ASN1Template getTemplate() {
return templateInstance;
}
/**
* Tests the DER encoding and decoding of the INTEGER class.
*/
public static void main(String args[]) {
try {
int[] Is = new int[11];
int[][] Bs = new int[11][];
int i = 0;
Is[i] = 0;
Bs[i++] = new int[]{ 0x02, 0x01, 0x00 };
Is[i] = 1;
Bs[i++] = new int[]{ 0x02, 0x01, 0x01 };
Is[i] = -1;
Bs[i++] = new int[]{ 0x02, 0x01, 0xff };
Is[i] = 127;
Bs[i++] = new int[]{ 0x02, 0x01, 0x7f };
Is[i] = 128;
Bs[i++] = new int[]{ 0x02, 0x02, 0x00, 0x80 };
Is[i] = 255;
Bs[i++] = new int[]{ 0x02, 0x02, 0x00, 0xff };
Is[i] = 256;
Bs[i++] = new int[]{ 0x02, 0x02, 0x01, 0x00 };
Is[i] = -128;
Bs[i++] = new int[]{ 0x02, 0x01, 0x80 };
Is[i] = -129;
Bs[i++] = new int[]{ 0x02, 0x02, 0xff, 0x7f };
Is[i] = 43568;
Bs[i++] = new int[]{ 0x02, 0x03, 0x00, 0xaa, 0x30 };
Is[i] = -43568;
Bs[i++] = new int[]{ 0x02, 0x03, 0xff, 0x55, 0xd0 };
for( i = 0; i < Is.length; i++) {
INTEGER I = new INTEGER( Is[i] );
byte[] compare = I.encode();
if( ! arraysEqual(compare, Bs[i]) ) {
System.err.println("Encoding FAILED: "+Is[i]);
System.exit(-1);
}
ByteArrayInputStream bis = new ByteArrayInputStream(compare);
Template template = new Template();
INTEGER create = (INTEGER) template.decode(bis);
if( create.intValue() != Is[i] ) {
System.err.println("Decoding FAILED: "+Is[i]);
System.exit(-1);
}
}
System.out.println("PASS");
} catch( Exception e ) {
e.printStackTrace();
}
}
private static boolean arraysEqual(byte[] bytes, int[] ints) {
if(bytes == null || ints == null) {
return false;
}
if(bytes.length != ints.length) {
return false;
}
for( int i=0; i < bytes.length; i++) {
if( bytes[i] != (byte)ints[i] ) {
return false;
}
}
return true;
}
///////////////////////////////////////////////////////////////////////
// INTEGER.Template
// This is a nested class.
//
public static class Template implements ASN1Template {
Tag getTag() {
return INTEGER.TAG;
}
public boolean tagMatch(Tag tag) {
return( tag.equals(INTEGER.TAG));
}
public ASN1Value
decode(InputStream derStream)
throws InvalidBERException, IOException
{
return decode( getTag(), derStream );
}
public ASN1Value
decode(Tag tag, InputStream derStream)
throws InvalidBERException, IOException
{
try {
ASN1Header wrapper = new ASN1Header(derStream);
wrapper.validate(tag, FORM);
// Is length < 1 ?
if( wrapper.getContentLength() < 1 ) {
throw new InvalidBERException("Invalid 0 length for INTEGER");
}
byte[] valBytes = new byte[ (int) wrapper.getContentLength() ];
ASN1Util.readFully(valBytes, derStream);
return new INTEGER( valBytes );
} catch(InvalidBERException e) {
throw new InvalidBERException(e, "INTEGER");
}
}
} // end of class Template
}
jss-4.4.3/jss/org/mozilla/jss/asn1/InvalidBERException.java 0000664 0000000 0000000 00000004032 13261450000 0023446 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.util.Vector;
/**
* An exception thrown when BER decoding fails.
*/
public class InvalidBERException extends java.lang.Exception {
private InvalidBERException child=null;
private Vector mesgList = new Vector();
public InvalidBERException(String mesg) {
super(mesg);
}
public void append(String mesg) {
mesgList.addElement(mesg);
}
public InvalidBERException(InvalidBERException e, String mesg) {
super(mesg);
child = e;
}
/**
* Prints out the exception class and error message, including
* all the nested exceptions.
*/
private void appendMessages(StringBuffer sb) {
int numMessages = mesgList.size();
for( int i=numMessages-1; i >= 0; --i ) {
sb.append(mesgList.elementAt(i));
sb.append(" >> ");
}
sb.append(getMessage());
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append( this.getClass().getName() );
sb.append(": ");
appendMessages(sb);
return sb.toString();
}
public String toStringNested() {
StringBuffer sb = new StringBuffer();
appendMessages(sb);
if( child != null ) {
sb.append(" >> ");
sb.append( child.toStringNested() );
}
return sb.toString();
}
public static class EOF extends InvalidBERException {
public EOF() {
super("Unexpected end-of-file encountered");
}
}
public static class InvalidChar extends InvalidBERException {
public InvalidChar(byte b, int offset) {
super("Invalid character ("+b+") encountered at offset "+offset);
}
public InvalidChar(char c, int offset) {
super("Invalid character ("+c+") encountered at offset"+offset);
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/Makefile 0000664 0000000 0000000 00000004037 13261450000 0020452 0 ustar 00root root 0000000 0000000 #! gmake
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#######################################################################
# (1) Include initial platform-independent assignments (MANDATORY). #
#######################################################################
include manifest.mn
#######################################################################
# (2) Include "global" configuration information. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
# (3) Include "component" configuration information. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/config/config.mk
#######################################################################
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
#######################################################################
include config.mk
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/rules.mk
#######################################################################
# (6) Execute "component" rules. (OPTIONAL) #
#######################################################################
#######################################################################
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################
run:
$(DEBUG_CMD) /share/builds/components/jdk/1.2.2_05a/SunOS/jre/bin/java -classpath $(JAVA_HOME)/lib/classes.zip:$(SOURCE_CLASSES_DIR)_DBG org.mozilla.jss.asn1.SEQUENCE /tmp/p10
jss-4.4.3/jss/org/mozilla/jss/asn1/NULL.java 0000664 0000000 0000000 00000003765 13261450000 0020436 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.IOException;
public class NULL implements ASN1Value {
public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 5);
public Tag getTag() {
return TAG;
}
public static final Form FORM = Form.PRIMITIVE;
public void encode(OutputStream ostream) throws IOException {
encode(TAG, ostream);
}
public void encode(Tag implicitTag, OutputStream ostream)
throws IOException
{
ASN1Header head = new ASN1Header(implicitTag, FORM, 0);
head.encode(ostream);
}
private static final NULL instance = new NULL();
public static NULL getInstance() {
return instance;
}
private static final Template templateInstance = new Template();
public static Template getTemplate() {
return templateInstance;
}
public static class Template implements ASN1Template {
public Tag getTag() {
return NULL.TAG;
}
public boolean tagMatch(Tag tag) {
return( tag.equals(NULL.TAG) );
}
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
return decode(getTag(), istream);
}
public ASN1Value decode(Tag implicitTag, InputStream istream)
throws IOException, InvalidBERException
{
try {
ASN1Header head = new ASN1Header(istream);
head.validate(implicitTag, FORM);
if( head.getContentLength() != 0 ) {
throw new InvalidBERException("Invalid length ("+
head.getContentLength()+") for NULL; only 0 is permitted");
}
return new NULL();
} catch(InvalidBERException e) {
throw new InvalidBERException(e, "NULL");
}
}
} // end of Template
}
jss-4.4.3/jss/org/mozilla/jss/asn1/OBJECT_IDENTIFIER.java 0000664 0000000 0000000 00000043506 13261450000 0022331 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.mozilla.jss.util.Assert;
import java.util.Vector;
import java.util.StringTokenizer;
public class OBJECT_IDENTIFIER implements ASN1Value {
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// Standard object identifiers
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
/**
* The OID space for EC
*/
public static final OBJECT_IDENTIFIER EC_PUBKEY_OID =
new OBJECT_IDENTIFIER( new long[]{1, 2, 840, 10045, 2, 1} );
/**
* The OID space for RSA Data Security, Inc.
*/
public static final OBJECT_IDENTIFIER RSADSI =
new OBJECT_IDENTIFIER( new long[]{1, 2, 840, 113549} );
/**
* The OID space for RSA's PKCS (public key cryptography standards).
*/
public static final OBJECT_IDENTIFIER PKCS =
RSADSI.subBranch(1);
/**
* The OID space for RSA's PKCS #1.
*/
public static final OBJECT_IDENTIFIER PKCS1 =
PKCS.subBranch(1);
/**
* The OID space for RSA's PKCS #2, which has since been folded into
* PKCS #1.
*/
public static final OBJECT_IDENTIFIER PKCS2 =
PKCS.subBranch(2);
/**
* The OID space for RSA's message digest algorithms.
*/
public static final OBJECT_IDENTIFIER RSA_DIGEST = RSADSI.subBranch(2);
/**
* The OID space for RSA's password-based encryption standard.
*/
public static final OBJECT_IDENTIFIER PKCS5 = PKCS.subBranch(5);
/**
* The OID space for RSA's Selected Attribute Types standard, PKCS #9.
*/
public static final OBJECT_IDENTIFIER PKCS9 = PKCS.subBranch(9);
/**
* The OID space for RSA's personal information exchange syntax standard.
*/
public static final OBJECT_IDENTIFIER PKCS12 = PKCS.subBranch(12);
/**
* The OID space for RSA's ciphers.
*/
public static final OBJECT_IDENTIFIER RSA_CIPHER = RSADSI.subBranch(3);
/**
* The OID space for FIPS standardized algorithms.
*/
public static final OBJECT_IDENTIFIER ALGORITHM =
new OBJECT_IDENTIFIER( new long[] { 1, 3, 14, 3, 2 } );
/**
* The OID space for FIPS-180-2 SHA256/SHA384/SHA512 standardized algorithms.
*/
public static final OBJECT_IDENTIFIER HASH_ALGORITHM =
new OBJECT_IDENTIFIER( new long[] {2, 16, 840, 1, 101, 3, 4, 2 } );
/**
* The OID space for PKIX.
*/
public static final OBJECT_IDENTIFIER PKIX =
new OBJECT_IDENTIFIER( new long[] { 1, 3, 6, 1, 5, 5, 7 } );
public static final OBJECT_IDENTIFIER
id_cmc = PKIX.subBranch( 7 );
/**
* CMC control attributes
*/
public static final OBJECT_IDENTIFIER
id_cmc_cMCStatusInfo = id_cmc.subBranch(1);
public static final OBJECT_IDENTIFIER
id_cmc_identification = id_cmc.subBranch(2);
public static final OBJECT_IDENTIFIER
id_cmc_identityProof = id_cmc.subBranch(3);
public static final OBJECT_IDENTIFIER
id_cmc_dataReturn = id_cmc.subBranch(4);
public static final OBJECT_IDENTIFIER
id_cmc_transactionId = id_cmc.subBranch(5);
public static final OBJECT_IDENTIFIER
id_cmc_senderNonce = id_cmc.subBranch(6);
public static final OBJECT_IDENTIFIER
id_cmc_recipientNonce = id_cmc.subBranch(7);
public static final OBJECT_IDENTIFIER
id_cmc_addExtensions = id_cmc.subBranch(8);
public static final OBJECT_IDENTIFIER
id_cmc_encryptedPOP = id_cmc.subBranch(9);
public static final OBJECT_IDENTIFIER
id_cmc_decryptedPOP = id_cmc.subBranch(10);
public static final OBJECT_IDENTIFIER
id_cmc_lraPOPWitness = id_cmc.subBranch(11);
public static final OBJECT_IDENTIFIER
id_cmc_getCert = id_cmc.subBranch(15);
public static final OBJECT_IDENTIFIER
id_cmc_getCRL = id_cmc.subBranch(16);
public static final OBJECT_IDENTIFIER
id_cmc_revokeRequest = id_cmc.subBranch(17);
public static final OBJECT_IDENTIFIER
id_cmc_regInfo = id_cmc.subBranch(18);
public static final OBJECT_IDENTIFIER
id_cmc_responseInfo = id_cmc.subBranch(19);
public static final OBJECT_IDENTIFIER
id_cmc_QueryPending = id_cmc.subBranch(21);
public static final OBJECT_IDENTIFIER
id_cmc_idPOPLinkRandom = id_cmc.subBranch(22);
public static final OBJECT_IDENTIFIER
id_cmc_idPOPLinkWitness = id_cmc.subBranch(23);
public static final OBJECT_IDENTIFIER
id_cmc_idConfirmCertAcceptance = id_cmc.subBranch(24);
// rfc 5272
public static final OBJECT_IDENTIFIER
id_cmc_statusInfoV2 = id_cmc.subBranch(25);
public static final OBJECT_IDENTIFIER
id_cmc_trustedAnchors = id_cmc.subBranch(26);
public static final OBJECT_IDENTIFIER
id_cmc_authData = id_cmc.subBranch(27);
public static final OBJECT_IDENTIFIER
id_cmc_batchRequests = id_cmc.subBranch(28);
public static final OBJECT_IDENTIFIER
id_cmc_batchResponses = id_cmc.subBranch(29);
public static final OBJECT_IDENTIFIER
id_cmc_publishCert = id_cmc.subBranch(30);
public static final OBJECT_IDENTIFIER
id_cmc_modCertTemplate = id_cmc.subBranch(31);
public static final OBJECT_IDENTIFIER
id_cmc_controlProcessed = id_cmc.subBranch(32);
public static final OBJECT_IDENTIFIER
id_cmc_popLinkWitnessV2 = id_cmc.subBranch(33);
public static final OBJECT_IDENTIFIER
id_cmc_identityProofV2 = id_cmc.subBranch(34);
public static final OBJECT_IDENTIFIER
id_cct = PKIX.subBranch( 12 );
public static final OBJECT_IDENTIFIER
id_cct_PKIData = id_cct.subBranch( 2 );
public static final OBJECT_IDENTIFIER
id_cct_PKIResponse = id_cct.subBranch( 3 );
public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 6);
public Tag getTag() {
return TAG;
}
public static final Form FORM = Form.PRIMITIVE;
private long[] numbers;
/**
* Creates an OBJECT_IDENTIFIER from an array of longs, which constitute
* the numbers that make up the OBJECT IDENTIFIER.
*/
public OBJECT_IDENTIFIER( long[] numbers ) {
checkLongArray(numbers);
this.numbers = numbers;
}
/**
* Checks the given array of numbers to see if it is a valid OID.
* This is not an exhaustive test, it just looks for obvious problems.
* It will throw an assertion if a problem is found. With DEBUG turned
* off, it just checks for null.
*/
private static void checkLongArray(long[] numbers) {
Assert._assert(numbers != null);
if(numbers == null) {
throw new NullPointerException();
}
Assert._assert(numbers.length >= 2);
Assert._assert( numbers[0]==0 || numbers[0]==1 || numbers[0]==2 );
}
/**
* Creates an OBJECT_IDENTIFIER from a String version. The proper format
* for the OID string is dotted numbers, for example:
* "3.2.456.53.23.64
".
*
* Because the toString() method here provides a different format, we also
* allow that format, for example:
* "{3 2 456 53 23 64}
".
*
* @exception NumberFormatException If the given string cannot be
* parsed into an OID.
*/
public OBJECT_IDENTIFIER( String dottedOID ) throws NumberFormatException {
if( dottedOID == null || dottedOID.length()==0 ) {
throw new NumberFormatException("OID string is zero-length");
}
if (dottedOID.startsWith("{")) {
// input string is of the format provided by OBJECT_IDENTIFIER,toString()
// convert this first to dotted OID
// remove the leading and trailing brackets
dottedOID = dottedOID.substring(1, dottedOID.length()-1);
// convert spaces to dots
dottedOID = dottedOID.replaceAll(" ", ".");
}
StringTokenizer stok = new StringTokenizer(dottedOID, ".");
numbers = new long[ stok.countTokens() ];
int i = 0;
while(stok.hasMoreElements()) {
numbers[i++] = Long.parseLong( stok.nextToken() );
}
Assert._assert( i == numbers.length );
checkLongArray(numbers);
}
public long[] getNumbers() {
return numbers;
}
public int hashCode() {
int code = 1;
for(int i = 0; i < numbers.length; i++) {
code = (int) (code + numbers[i])*10;
}
return code;
}
/**
* Creates a new OBJECT_IDENTIFIER that is a sub-branch of this one.
* For example, if OBJECT_IDENTIFIER oid
has the value
* { 1 3 5 6 },
* then calling oid.subBranch(4)
would return a new
* OBJECT_IDENTIFIER with the value { 1 3 5 6 4 }.
*/
public OBJECT_IDENTIFIER subBranch(long num) {
long[] nums = new long[ numbers.length + 1];
System.arraycopy(numbers, 0, nums, 0, numbers.length);
nums[numbers.length] = num;
return new OBJECT_IDENTIFIER(nums);
}
/**
* Creates a new OBJECT_IDENTIFIER that is a sub-branch of this one.
* For example, if OBJECT_IDENTIFIER oid
has the value
* { 1 3 5 6 },
* then calling oid.subBranch(new long[]{ 4, 3})
* would return a new
* OBJECT_IDENTIFIER with the value { 1 3 5 6 4 3}.
*/
public OBJECT_IDENTIFIER subBranch(long[] newNums) {
long[] nums = new long[ numbers.length + newNums.length];
System.arraycopy(numbers, 0, nums, 0, numbers.length);
System.arraycopy(newNums, 0, nums, numbers.length, newNums.length);
return new OBJECT_IDENTIFIER(nums);
}
public boolean equals(Object obj) {
if(obj == null || ! (obj instanceof OBJECT_IDENTIFIER)) {
return false;
}
long[] nums = ((OBJECT_IDENTIFIER)obj).numbers;
if( nums.length != numbers.length ) {
return false;
}
for(int i = 0; i < nums.length; i++) {
if( nums[i] != numbers[i] ) {
return false;
}
}
return true;
}
public String toString() {
String ret = "{" + String.valueOf(numbers[0]);
for(int i=1; i < numbers.length; i++) {
ret = ret + " " + numbers[i];
}
ret += "}";
return ret;
}
public String toDottedString() {
String ret = String.valueOf(numbers[0]);
for(int i=1; i < numbers.length; i++) {
ret = ret + "." + numbers[i];
}
return ret;
}
public void encode(OutputStream ostream) throws IOException {
encode(TAG, ostream);
}
private byte[] encodedContents = null;
/**
* Gets the encoding of the contents, or a cached copy.
* Since the content encoding is the same regardless of the Tag,
* this only needs to be computed once.
*/
private byte[] getEncodedContents() {
if( encodedContents == null ) {
encodedContents = computeEncodedContents();
}
return encodedContents;
}
// We cache our encoding for a given tag. 99% of the time, only
// one tag will be used for an instance, so we will get a cache hit.
// In the remaining 1%, we'll have to recompute the encoding.
byte[] cachedEncoding=null;
Tag tagForCache=null;
/**
* Returns the encoding for the given tag. If the encoding for
* this tag was previously computed (and no encoding for a different
* tag has since been computed), this method returns a cached copy.
* Otherwise, the encoding will be recomputed.
*/
private byte[] getEncoding(Tag tag) {
if( ! tag.equals(tagForCache) ) {
// recompute for new tag
ByteArrayOutputStream out = new ByteArrayOutputStream();
ASN1Header head = getHeader(tag);
try {
head.encode(out);
} catch( IOException e ) {
// should never happen on a byte array output stream
Assert.notReached("exception while encoding ASN.1 header");
}
out.write( getEncodedContents(), 0, getEncodedContents().length );
tagForCache = tag;
cachedEncoding = out.toByteArray();
}
return cachedEncoding;
}
/**
* Compute the ASN1 header for this tag.
*/
private ASN1Header getHeader(Tag implicitTag) {
return new ASN1Header( implicitTag, FORM, getEncodedContents().length );
}
/**
* Actually computes the encoding of this object identifier.
*/
private byte[] computeEncodedContents() {
ByteArrayOutputStream out = new ByteArrayOutputStream();
// handle first number
Assert._assert(numbers.length >= 2);
long n = numbers[0];
Assert._assert( n == 0 || n == 1 || n == 2 );
long outb = ( numbers[0] * 40 ) + numbers[1];
Assert._assert( ((byte)outb) == outb );
out.write( (byte)outb );
// handle consecutive numbers
for( int i = 2; i < numbers.length; i++ ) {
n = numbers[i];
Assert._assert( n >= 0 );
// array of output bytes, in reverse order. 10 bytes, at 7 bits
// per byte, is 70 bits, which is more than enough to handle
// the maximum value of a long, which takes up 63 bits.
byte[] rev = new byte[10];
int idx=0; // index into reversed bytes
// Create reversed byte list
do {
rev[idx++] = (byte) (n % 128);
n = n / 128;
} while( n > 0 );
idx--; // backup to point to last element
// now print them in reverse order
while( idx > 0 ) {
// all but last byte have MSB==1
out.write( rev[idx--] | 0x80 );
}
Assert._assert(idx == 0);
// last byte has MSB==0
out.write( rev[0] );
}
return out.toByteArray();
}
public void encode(Tag implicitTag, OutputStream ostream)
throws IOException
{
ostream.write( getEncoding(implicitTag) );
}
private static final Template templateInstance = new Template();
public static Template getTemplate() {
return templateInstance;
}
///////////////////////////////////////////////////////////////////////
// OBJECT_IDENTIFIER.Template
//
public static class Template implements ASN1Template {
public Tag getTag() {
return OBJECT_IDENTIFIER.TAG;
}
public boolean tagMatch(Tag tag) {
return( tag.equals(OBJECT_IDENTIFIER.TAG) );
}
public Form getForm() {
return OBJECT_IDENTIFIER.FORM;
}
public boolean formMatch(Form form) {
return( form == OBJECT_IDENTIFIER.FORM );
}
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
return decode(getTag(), istream);
}
public ASN1Value decode(Tag implicitTag, InputStream istream)
throws IOException, InvalidBERException
{
try {
ASN1Header head = new ASN1Header(istream);
long remainingContent = head.getContentLength();
// Check the information gleaned from the header
if( ! head.getTag().equals( implicitTag ) ) {
throw new InvalidBERException("Incorrect tag for "+
"OBJECT IDENTIFIER: "+ head.getTag() );
}
if( head.getForm() != getForm() ) {
throw new InvalidBERException("Incorrect form for OBJECT "+
"IDENTIFIER");
}
if( remainingContent < 1 ) {
throw new InvalidBERException("Invalid 0 length for OBJECT"+
" IDENTIFIER");
}
Vector numberV = new Vector();
// handle first byte, which contains first two numbers
byte b = readByte(istream);
remainingContent--;
long num = b % 40;
numberV.addElement( new Long( b % 40 ) ); // second number
numberV.insertElementAt( new Long( b / 40 ), 0); // first number
// handle the rest of the numbers
while( remainingContent > 0 ) {
num = 0;
// keep reading until MSB == 0
int bitcount=0;
do {
if( (bitcount+=7) > 63 ) {
// we're about to overflow our long
throw new InvalidBERException("OBJECT IDENTIFIER "+
"element too long; max is 63 bits");
}
b = readByte(istream);
remainingContent--;
num <<= 7;
num |= (b & 0x7f);
} while( (b & 0x80) != 0 );
numberV.addElement( new Long( num ) );
}
// convert Vector to array
long numbers[] = new long[ numberV.size() ];
for(int i = 0; i < numbers.length; i++) {
numbers[i] = ((Long)numberV.elementAt(i)).longValue();
}
// create OBJECT_IDENTIFIER from array
return new OBJECT_IDENTIFIER(numbers);
} catch(InvalidBERException e) {
throw new InvalidBERException(e, "OBJECT IDENTIFIER");
}
}
/**
* Reads in a byte from the stream, throws an InvalidBERException
* if EOF is reached.
*/
private static byte readByte(InputStream istream)
throws InvalidBERException, IOException
{
int n = istream.read();
if( n == -1 ) {
throw new InvalidBERException("End-of-file reached while "+
"decoding OBJECT IDENTIFIER");
}
Assert._assert( (n & 0xff) == n );
return (byte) n;
}
} // end of OBJECT_IDENTIFIER.Template
}
jss-4.4.3/jss/org/mozilla/jss/asn1/OCTET_STRING.java 0000664 0000000 0000000 00000006113 13261450000 0021616 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
public class OCTET_STRING implements ASN1Value {
public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 4);
public Tag getTag() {
return TAG;
}
public static final Form FORM = Form.PRIMITIVE;
byte[] data;
private OCTET_STRING() { }
public OCTET_STRING( byte[] data ) {
this.data = data;
}
public byte[] toByteArray() {
return data;
}
public void encode(OutputStream ostream) throws IOException {
// use getTag() so we can be subclassed
encode(getTag(), ostream);
}
public void encode(Tag implicitTag, OutputStream ostream)
throws IOException
{
ASN1Header head = new ASN1Header(implicitTag, FORM, data.length);
head.encode(ostream);
ostream.write(data);
}
private static final Template templateInstance = new Template();
public static Template getTemplate() {
return templateInstance;
}
public static class Template implements ASN1Template {
public Tag getTag() {
return TAG;
}
public boolean tagMatch(Tag tag) {
return( TAG.equals(tag) );
}
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
return decode(getTag(), istream);
}
// this can be overridden by subclasses
protected ASN1Value generateInstance(byte[] bytes) {
return new OCTET_STRING( bytes );
}
// this can be overridden by subclasses
protected String getName() {
return "OCTET_STRING";
}
public ASN1Value decode(Tag implicitTag, InputStream istream)
throws IOException, InvalidBERException
{
try {
ASN1Header head = new ASN1Header(istream);
head.validate(implicitTag);
byte[] data;
if( head.getContentLength() == -1 ) {
// indefinite length encoding
ASN1Header ahead;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
do {
ahead = ASN1Header.lookAhead( istream );
if( ! ahead.isEOC() ) {
OCTET_STRING.Template ot = new OCTET_STRING.Template();
OCTET_STRING os = (OCTET_STRING) ot.decode(istream);
bos.write( os.toByteArray() );
}
} while( ! ahead.isEOC() );
// consume EOC
ahead = new ASN1Header(istream);
data = bos.toByteArray();
} else {
data = new byte[ (int) head.getContentLength() ];
ASN1Util.readFully(data, istream);
}
return generateInstance(data);
} catch( InvalidBERException e ) {
throw new InvalidBERException(e, getName());
}
}
} // end of Template
}
jss-4.4.3/jss/org/mozilla/jss/asn1/PrintableString.java 0000664 0000000 0000000 00000007031 13261450000 0022761 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.CharConversionException;
public class PrintableString extends CharacterString implements ASN1Value {
public PrintableString(char[] chars) throws CharConversionException {
super(chars);
}
public PrintableString(String s) throws CharConversionException {
super(s);
}
CharConverter getCharConverter() {
return new PrintableConverter();
}
public static final Tag TAG = new Tag( Tag.UNIVERSAL, 19 );
public static final Form FORM = Form.PRIMITIVE;
public Tag getTag() {
return TAG;
}
/**
* Returns a singleton instance of the decoding template for this class.
*/
public static Template getTemplate() {
return templateInstance;
}
private static final Template templateInstance = new Template();
// nested class
public static class Template
extends CharacterString.Template implements ASN1Template
{
protected Tag getTag() {
return TAG;
}
public boolean tagMatch(Tag tag) {
return TAG.equals(tag);
}
protected CharConverter getCharConverter() {
return new PrintableConverter();
}
protected CharacterString generateInstance(char[] chars)
throws CharConversionException
{
return new PrintableString(chars);
}
protected String typeName() {
return "PrintableString";
}
}
private static class PrintableConverter implements CharConverter {
private static boolean[] isPrintable = new boolean[128];
static {
char b;
for(b='A'; b <= 'Z'; b++) {
isPrintable[b] = true;
}
for(b='a'; b <= 'z'; b++) {
isPrintable[b] = true;
}
for(b='0'; b <= '9'; b++) {
isPrintable[b] = true;
}
isPrintable[' '] = true;
isPrintable['\''] = true;
isPrintable['('] = true;
isPrintable[')'] = true;
isPrintable['+'] = true;
isPrintable[','] = true;
isPrintable['-'] = true;
isPrintable['.'] = true;
isPrintable['/'] = true;
isPrintable[':'] = true;
isPrintable['='] = true;
isPrintable['?'] = true;
}
public char[] byteToChar(byte[] bytes, int offset, int len)
throws CharConversionException
{
char[] chars = new char[len];
int c; // char index
int b; // byte index
for(c=0, b=offset; c < len; b++, c++) {
if( (bytes[b] & 0x80) != 0 || !isPrintable[bytes[b]] ) {
/* fix for bug 359010 - don't throw, just skip
* throw new CharConversionException(bytes[b]+ " is not "+
* "a valid character for a PrintableString");
*/
} else {
chars[c] = (char) bytes[b];
}
}
return chars;
}
public byte[] charToByte(char[] chars, int offset, int len)
throws CharConversionException
{
byte[] bytes = new byte[len];
int c; // char index
int b; // byte index
for(c=0, b=0; b < len; b++, c++) {
if( (chars[c] & 0xff80) != 0 || !isPrintable[chars[c]] ) {
throw new CharConversionException(chars[c]+ " is not "+
"a valid character for a PrintableString");
}
bytes[b] = (byte) (chars[c] & 0x7f);
}
return bytes;
}
} // end of char converter
}
jss-4.4.3/jss/org/mozilla/jss/asn1/SEQUENCE.java 0000664 0000000 0000000 00000060717 13261450000 0021074 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.util.Vector;
import org.mozilla.jss.util.Assert;
import java.math.BigInteger;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
/**
* An ASN.1 SEQUENCE. This class is an ordered collection of ASN.1 values.
* It has an interface similar to a Java Vector
.
* Null entries may be added; they will be skipped when encoded.
*/
public class SEQUENCE extends SET implements ASN1Value {
public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 16);
public Tag getTag() {
return TAG;
}
public static Template getTemplate() {
return new Template();
}
/**
* Writes the DER encoding to the given output stream,
* using the given implicit tag.
*/
public void encode(Tag implicitTag, OutputStream ostream)
throws IOException
{
BERencode(implicitTag, ostream);
}
// SET.Element and SEQUENCE.Element are identical types. We could
// have just reused SET.Element, but that would have been a bit
// confusing for users.
private static class Element extends SET.Element {
public Element( ASN1Value val ) {
super(val);
}
public Element( Tag implicitTag, ASN1Value val) {
super(implicitTag, val);
}
}
/**
* A class for constructing a SEQUENCE
from its BER encoding.
* It is an ordered collection of sub-templates. Each sub-template can be
* marked optional, or a default value can be given.
*/
public static class Template implements ASN1Template {
private Vector elements = new Vector();
private void addElement(Element el) {
elements.addElement( el );
}
private void insertElementAt(Element e, int index) {
elements.insertElementAt(e, index);
}
/**
* Adds a sub-template to the end of this SEQUENCE template. For example,
* if the ASN.1 included:
*
* MySequence ::= SEQUENCE {
* item SubType,
* ... }
*
* the "item" element would be added to the MySequence template with:
*
* mySequence.addElement( new SubType.Template() );
*
*/
public void addElement( ASN1Template t ) {
addElement( new Element(null, t, false) );
}
/**
* Inserts the template at the given index.
*/
public void insertElementAt( ASN1Template t, int index )
{
insertElementAt( new Element(null, t, false), index );
}
/**
* Adds a sub-template to the end of this SEQUENCE template, with the
* given implicit tag. For example, if the ASN.1 were:
*
* MySequence ::= SEQUENCE {
* item [0] IMPLICIT SubType,
* ... }
*
* the "item" element would be added to the MySequence template with:
*
* mySequence.addElement( new Tag(0), new SubType.Template());
*
*/
public void addElement( Tag implicitTag, ASN1Template t ) {
addElement( new Element(implicitTag, t, false) );
}
/**
* Inserts the template with the given implicit tag at the given index.
*/
public void insertElementAt( Tag implicit, ASN1Template t,
int index )
{
insertElementAt( new Element(implicit, t, false), index );
}
/**
* Adds an optional sub-template. For example, if the ASN.1 were:
*
* MySequence ::= SEQUENCE {
* item SubType OPTIONAL,
* ... }
*
* the "item" element would be added to the MySequence template with:
*
* mySequence.addOptionalElement( new SubType.Template() );
*
*/
public void addOptionalElement( ASN1Template t ) {
addElement( new Element(null, t, true) );
}
/**
* Inserts the optional template at the given index.
*/
public void insertOptionalElementAt( ASN1Template t, int index )
{
insertElementAt( new Element(null, t, true), index );
}
/**
* Adds an optional sub-template with an implicit tag. For example,
* if the ASN.1 were:
*
* MySequence ::= SEQUENCE {
* item [0] IMPLICIT SubType OPTIONAL,
* ... }
*
* the "item" element would be added to the MySequence template with:
*
* mySequence.addOptionalElement( new SubType.Template() );
*
*/
public void addOptionalElement( Tag implicitTag, ASN1Template t ) {
addElement( new Element(implicitTag, t, true) );
}
/**
* Inserts the optional template with the given default
* value at the given index.
*/
public void insertOptionalElementAt( Tag implicit, ASN1Template t,
int index )
{
insertElementAt( new Element(implicit, t, true), index );
}
/**
* Adds a sub-template with a default value. For example,
* if the ASN.1 were:
*
* MySequence ::= SEQUENCE {
* version INTEGER DEFAULT 1,
* ... }
*
* the "item" element would be added to the MySequence template with:
*
* mySequence.addElement( new INTEGER.Template(), new INTEGER(1) );
*
* @param def The default value for this field, which will be used if
* no value is supplied by the encoded structure. It must be of
* the same type as what the template would produce.
*/
public void addElement( ASN1Template t, ASN1Value def ) {
addElement( new Element(null, t, def) );
}
/**
* Inserts the template with the given default
* value at the given index.
*/
public void insertElementAt( ASN1Template t, ASN1Value def, int index )
{
insertElementAt( new Element(null, t, def), index );
}
/**
* Adds a sub-template with a default value and an implicit tag.
* For example, if the ASN.1 were:
*
* MySequence ::= SEQUENCE {
* version [0] IMPLICIT INTEGER DEFAULT 1,
* ... }
*
* the "item" element would be added to the MySequence template with:
*
* mySequence.addElement( new Tag(0), new INTEGER.Template(),
* new INTEGER(1) );
*
* @param def The default value for this field, which will be used if
* no value is supplied by the encoded structure. It must be of
* the same type as what the template would produce.
*/
public void addElement( Tag implicitTag, ASN1Template t, ASN1Value def) {
addElement( new Element(implicitTag, t, def) );
}
/**
* Inserts the template with the given implicit tag and given default
* value at the given index.
*/
public void insertElementAt( Tag implicit, ASN1Template t, ASN1Value def,
int index )
{
insertElementAt( new Element(implicit, t, def), index );
}
/**
* Returns the implicit tag of the item stored at the given index.
* May be NULL if no implicit tag was specified.
*/
public Tag implicitTagAt( int index ) {
return ((Element)elements.elementAt(index)).getImplicitTag();
}
/**
* Returns the sub-template stored at the given index.
*/
public ASN1Template templateAt( int index ) {
return ((Element)elements.elementAt(index)).getTemplate();
}
/**
* Returns whether the sub-template at the given index is optional.
*/
public boolean isOptionalAt( int index ) {
return ((Element)elements.elementAt(index)).isOptional();
}
/**
* Returns the default value for the sub-template at the given index.
* May return NULL if no default value was specified.
*/
public ASN1Value defaultAt( int index ) {
return ((Element)elements.elementAt(index)).getDefault();
}
/**
* Returns the number of elements in this SEQUENCE template.
*/
public int size() {
return elements.size();
}
/**
* Removes all sub-templates from this SEQUENCE template.
*/
public void removeAllElements() {
elements.removeAllElements();
}
/**
* Removes the sub-template at the given index.
*/
public void removeElementAt(int index) {
elements.removeElementAt(index);
}
Tag getTag() {
return SEQUENCE.TAG;
}
public boolean tagMatch(Tag tag) {
return( tag.equals(SEQUENCE.TAG) );
}
/**
* Decodes a SEQUENCE from its BER encoding.
*/
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
return decode(getTag(), istream);
}
/**
* Decodes a SEQUENCE from its BER encoding, where the SEQUENCE itself has
* an implicit tag.
*/
public ASN1Value decode(Tag tag, InputStream istream)
throws IOException, InvalidBERException
{
int index = 0;
try {
ASN1Header header = new ASN1Header(istream);
header.validate( tag, Form.CONSTRUCTED );
// will be -1 for indefinite encoding
long remainingContent = header.getContentLength();
boolean repeatableElement=false;
SEQUENCE seq = new SEQUENCE();
ASN1Header lookAhead=null;
// go through the whole template
for( index = 0; index < size(); index++ ) {
// find out about the next item
if( remainingContent == 0 ) {
lookAhead = null;
} else {
// remainingContent > 0 or remainingContent == -1, which means
// indefinite encoding.
lookAhead = ASN1Header.lookAhead(istream);
}
// skip over items that don't match. Hopefully they are
// optional or have a default. Otherwise, it's an error.
Element e = (Element) elements.elementAt(index);
if( (lookAhead == null) || lookAhead.isEOC() ||
! e.tagMatch( lookAhead.getTag() ) )
{
if( e.isRepeatable() ) {
repeatableElement = true;
} else if( e.isOptional() ) {
// put an empty entry into the SEQUENCE
SEQUENCE.Element se = new SEQUENCE.Element(null, null );
seq.addElement( null );
} else if( e.getDefault() != null ) {
// use the default
seq.addElement( e.getDefault() );
} else {
String tagDesc;
if( lookAhead == null ) {
tagDesc = "(null)";
} else {
tagDesc = lookAhead.getTag().toString();
}
throw new InvalidBERException("Missing item #" + index +
": found " + tagDesc );
}
continue;
}
// Decode this element
ASN1Template t = e.getTemplate();
ASN1Value val;
CountingStream countstream = new CountingStream(istream);
if( e.getImplicitTag() == null ) {
val = t.decode(countstream);
} else {
val = t.decode(e.getImplicitTag(), countstream);
}
// Decrement remaining count
long len = countstream.getNumRead();
if( remainingContent != -1 ) {
if( remainingContent < len ) {
// this item went past the end of the SEQUENCE
throw new InvalidBERException("Item went "+
(len-remainingContent)+" bytes past the end of"+
" the SEQUENCE");
}
remainingContent -= len;
}
// Store this element in the SEQUENCE
if( e.producesOutput() ) {
if( e.getImplicitTag() == null ) {
// no implicit tag
seq.addElement( val );
} else {
// there is an implicit tag
seq.addElement( e.getImplicitTag(), val );
}
}
// If this element is repeatable, don't go on to the next element
if( e.isRepeatable() ) {
repeatableElement = true;
index--;
}
}
if( remainingContent > 0 ) {
throw new InvalidBERException("SEQUENCE is " + remainingContent +
" bytes longer than expected");
}
Assert._assert( remainingContent == 0 || remainingContent == -1 );
// If this was indefinite-length encoding, consume the end-of-contents
if( remainingContent == -1 ) {
lookAhead = new ASN1Header(istream);
if( ! lookAhead.isEOC() ) {
throw new InvalidBERException("No end-of-contents marker");
}
}
// Make sure we stayed in sync
if( ! repeatableElement ) {
Assert._assert(index == seq.size());
}
return seq;
} catch(InvalidBERException e) {
e.append("SEQUENCE(item #" +index + ")");
throw e;
}
}
/**
* An element of a SEQUENCE template. For each sub-template, contains the
* template, its optionality, its implicit tag, and its default value.
*/
static class Element {
/**
* Creates a new element, which may or may not be optional.
*/
public Element(Tag implicitTag, ASN1Template type, boolean optional)
{
this(implicitTag, type, optional, true);
}
/**
* Creates a new element, which may or may not be optional.
*/
public Element(Tag implicitTag, ASN1Template type, boolean optional,
boolean doesProduceOutput)
{
this.type = type;
defaultVal = null;
this.optional = optional;
this.implicitTag = implicitTag;
this.doesProduceOutput = doesProduceOutput;
}
/**
* Creates a new element with a default value.
*/
public Element(Tag implicitTag, ASN1Template type, ASN1Value defaultVal)
{
this.type = type;
this.defaultVal = defaultVal;
optional = false;
this.implicitTag = implicitTag;
}
private boolean doesProduceOutput = true;
boolean producesOutput() {
return doesProduceOutput;
}
// repeatability is provided to allow for SEQUENCE OF SIZE
// constructs. It is package private.
private boolean repeatable;
void makeRepeatable() {
repeatable = true;
}
boolean isRepeatable() {
return repeatable;
}
private boolean optional;
public boolean isOptional() {
return optional;
}
private Tag implicitTag=null;
public Tag getImplicitTag() {
return implicitTag;
}
public boolean tagMatch(Tag tag) {
if( implicitTag != null ) {
return( implicitTag.equals(tag) );
} else {
return type.tagMatch(tag);
}
}
private ASN1Template type;
public ASN1Template getTemplate() {
return type;
}
private ASN1Value defaultVal=null;
public ASN1Value getDefault() {
return defaultVal;
}
}
} // End of SEQUENCE.Template
/**
* A Template for decoding SEQUENCE OF values. The main difference between
* a SEQUENCE.Template and a SEQUENCE.OF_Template is that a regular template
* specifies the exact ordering, number, and type of elements of the sequence,
* while
* an OF_Template has an indefinite number of elements, all the same type.
* For example, given:
*
* MyType ::= SEQUENCE OF Extension
*
* a MyType could be decoded with:
*
* SEQUENCE.OF_Template myTypeTemplate = new SEQUENCE.OF_Template( new
* Extension.Template) );
* SEQUENCE seq = (SEQUENCE) myTypeTemplate.decode(someInputStream);
*
* The number of Extension
s actually decoded could be found
* with seq.size()
.
*/
public static class OF_Template implements ASN1Template {
private OF_Template() { }
Template template; // a normal SEQUENCE template
public OF_Template(ASN1Template type) {
template = new Template();
Template.Element el = new Template.Element(null, type, true); //optional
el.makeRepeatable();
template.addElement( el );
}
public static OF_Template makeOutputlessOFTemplate(ASN1Template type) {
OF_Template t = new OF_Template();
t.template = new Template();
Template.Element el = new Template.Element(null, type, true, false);
el.makeRepeatable();
t.template.addElement(el);
return t;
}
public boolean tagMatch(Tag tag) {
return TAG.equals(tag);
}
/**
* Decodes a SEQUENCE OF from an input stream.
*/
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
return template.decode(istream);
}
/**
* Decodes a SEQUENCE OF with an implicit tag from an input stream.
*/
public ASN1Value decode(Tag implicitTag, InputStream istream)
throws IOException, InvalidBERException
{
return template.decode(implicitTag, istream);
}
}
public static void main(String args[]) {
try {
if(args.length > 0) {
// input
Template type = new Template();
type.addOptionalElement( new Tag(15), new INTEGER.Template() );
type.addElement( new Tag(16), new INTEGER.Template(),
new INTEGER(42) );
type.addElement( new INTEGER.Template() );
type.addElement( new BOOLEAN.Template() );
type.addElement( new INTEGER.Template() );
type.addOptionalElement( new Tag(12), new INTEGER.Template() );
type.addElement( new BOOLEAN.Template() );
type.addElement( new Tag(13), new INTEGER.Template(),
new INTEGER(53) );
type.addElement( new INTEGER.Template() );
type.addElement( new INTEGER.Template() );
type.addOptionalElement( new Tag(14), new INTEGER.Template() );
type.addElement( new OBJECT_IDENTIFIER.Template() );
type.addElement( new NULL.Template() );
type.addElement( new EXPLICIT.Template(
new Tag(27), new INTEGER.Template()));
type.addElement( new ENUMERATED.Template() );
type.addElement( new OCTET_STRING.Template() );
type.addElement( new IA5String.Template() );
CHOICE.Template choice = new CHOICE.Template();
choice.addElement( new Tag(23), new INTEGER.Template() );
choice.addElement( new BOOLEAN.Template() );
type.addElement( choice );
type.addElement( new BIT_STRING.Template() );
type.addElement( new ANY.Template() );
type.addElement( new PrintableString.Template() );
type.addElement( new OF_Template( new INTEGER.Template() ) );
type.addElement( new OF_Template( new INTEGER.Template() ) );
FileInputStream fin = new FileInputStream(args[0]);
System.out.println("Available: "+fin.available());
byte[] stuff = new byte[ fin.available() ];
ASN1Util.readFully(stuff, fin);
SEQUENCE s=null;
for( int i = 0; i < 1; i++) {
s = (SEQUENCE) type.decode( new ByteArrayInputStream(stuff) );
}
for(int i=0; i < s.size(); i ++ ) {
ASN1Value v = s.elementAt(i);
if(v instanceof ENUMERATED) {
ENUMERATED en = (ENUMERATED) v;
System.out.println("ENUMERATED: "+en);
} else if( v instanceof INTEGER ) {
INTEGER in = (INTEGER) v;
System.out.println("INTEGER: "+in);
} else if(v instanceof BOOLEAN ) {
BOOLEAN bo = (BOOLEAN) v;
System.out.println("BOOLEAN: "+bo);
} else if(v instanceof OBJECT_IDENTIFIER) {
OBJECT_IDENTIFIER oid = (OBJECT_IDENTIFIER) v;
System.out.println("OID: "+oid);
} else if(v instanceof NULL) {
NULL n = (NULL) v;
System.out.println("NULL");
} else if(v instanceof EXPLICIT) {
EXPLICIT ex = (EXPLICIT) v;
INTEGER in = (INTEGER) ex.getContent();
System.out.println("EXPLICIT ["+ex.getTag()+"]: "+
"INTEGER: "+in);
} else if(v instanceof OCTET_STRING) {
OCTET_STRING os = (OCTET_STRING) v;
byte[] bytes = os.toByteArray();
System.out.print("OCTET_STRING: ");
for(int j = 0; j < bytes.length; j++) {
System.out.print(bytes[j]+" ");
}
System.out.println("");
} else if( v instanceof CharacterString ) {
CharacterString cs = (CharacterString) v;
System.out.println("String: "+cs);
} else if( v instanceof BIT_STRING ) {
BIT_STRING bs = (BIT_STRING) v;
System.out.print("BIT_STRING: padCount="+
bs.getPadCount()+" : ");
byte[] bits = bs.getBits();
for(int j = 0; j < bits.length; j++) {
System.out.print(bits[j]+" ");
}
System.out.println("");
} else if( v instanceof ANY ) {
ANY any = (ANY) v;
Tag tag = any.getTag();
System.out.println("Got ANY, tag is "+tag);
ByteArrayInputStream bos =
new ByteArrayInputStream( any.getEncoded() );
INTEGER in = (INTEGER) new INTEGER.Template().decode(bos);
System.out.println(" INTEGER: "+in);
} else if(v instanceof SEQUENCE ) {
SEQUENCE seq = (SEQUENCE)v;
System.out.println("SEQUENCE: ");
for(int j=0; j < seq.size(); j++ ) {
INTEGER in = (INTEGER) seq.elementAt(j);
System.out.println(" INTEGER: "+in);
}
} else {
System.out.println("Unknown value");
}
}
} else {
// output
SEQUENCE seq = new SEQUENCE();
seq.addElement( new INTEGER(5) );
seq.addElement( new BOOLEAN(true) );
seq.addElement( new INTEGER(-322) );
seq.addElement( new BOOLEAN(false) );
seq.addElement( new INTEGER(0) );
seq.addElement( new INTEGER("2934293834242") );
seq.addElement( new OBJECT_IDENTIFIER(
new long[] { 1, 2, 127, 563, 1231982 } ) );
seq.addElement( new NULL() );
seq.addElement( new EXPLICIT( new Tag(27), new INTEGER(39) ));
seq.addElement( new ENUMERATED(983) );
seq.addElement( new OCTET_STRING( new byte[] {
(byte)0x0, (byte)0xff, (byte)0xcc} ) );
seq.addElement( new IA5String("foobar") );
seq.addElement( new Tag(23), new INTEGER(234) );
//seq.addElement( new BOOLEAN(false) );
byte[] bits = new byte[]{ (byte)0x80, (byte)0xff, (byte)0x0f };
seq.addElement( new BIT_STRING( bits, 3 ) );
seq.addElement( new INTEGER(82734) );
seq.addElement( new PrintableString("I'm printable??") );
SEQUENCE nested = new SEQUENCE();
nested.addElement( new INTEGER( 5 ) );
nested.addElement( new INTEGER( 6 ) );
seq.addElement( nested );
nested = new SEQUENCE();
seq.addElement( nested );
seq.encode(System.out);
System.out.flush();
}
} catch( Exception e) {
e.printStackTrace();
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/SET.java 0000664 0000000 0000000 00000064012 13261450000 0020307 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.math.BigInteger;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Vector;
import org.mozilla.jss.util.Assert;
import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
/**
* An ASN.1 SET, which is an unordered collection of ASN.1 values.
* It has an interface like a Java Vector, but the ordering is arbitrary.
* Null entries may be added; they will be skipped when encoding.
*/
public class SET implements ASN1Value {
public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 17);
public Tag getTag() {
return TAG;
}
protected static final Form FORM = Form.CONSTRUCTED;
// The elements of the set
protected Vector elements = new Vector();
private void addElement( Element e ) {
elements.addElement(e);
}
private void insertElementAt( Element e, int index ) {
elements.insertElementAt(e, index);
}
/**
* Adds an element to this SET.
*/
public void addElement( ASN1Value v ) {
addElement( new Element(v) );
}
/**
* Adds an element to this SET with the given implicit tag. For example,
* if the ASN.1 were:
*
* MyType ::= SET {
* item [0] IMPLICIT INTEGER,
* ... }
*
* then the "item" element could be added (with a sample value of 45)
* to the SET with:
*
* myTypeInstance.addElement( new Tag(0), new INTEGER(45) );
*
*/
public void addElement( Tag implicitTag, ASN1Value v ) {
addElement( new Element(implicitTag, v) );
}
/**
* Inserts an element at the given index.
*/
public void insertElementAt( ASN1Value v, int index ) {
insertElementAt( new Element(v), index );
}
/**
* Inserts an element with the given implicit tag at the given index.
*/
public void insertElementAt( Tag implicitTag, ASN1Value v, int index ) {
insertElementAt( new Element(implicitTag, v), index );
}
/**
* Returns the element at the given index in the SET.
*/
public ASN1Value elementAt( int index ) {
return ((Element)elements.elementAt(index)).getValue();
}
/**
* Returns the tag of the element at the given index. If the element
* has an implicit tag, that is returned. Otherwise, the tag of the
* underlying type is returned.
*/
public Tag tagAt( int index ) {
Tag implicit = ((Element)elements.elementAt(index)).getImplicitTag();
if( implicit != null ) {
return implicit;
} else {
return elementAt(index).getTag();
}
}
/**
* Returns the element with the given Tag, or null if no element exists
* with the given tag.
*/
public ASN1Value elementWithTag( Tag tag ) {
// hmmm...linear search for now, should use hashtable later
int size = elements.size();
for( int i=0; i < size; i++ ) {
Element e = (Element) elements.elementAt(i);
if( e.getTag().equals(tag) ) {
return e.getValue();
}
}
return null;
}
/**
* Returns the number of elements in this SET.
*/
public int size() {
return elements.size();
}
/**
* Removes all elements from this SET.
*/
public void removeAllElements() {
elements.removeAllElements();
}
/**
* Removes the element from the specified index.
*/
public void removeElementAt(int index) {
elements.removeElementAt(index);
}
/**
* Writes the DER encoding to the given output stream.
*/
public void encode(OutputStream ostream)
throws IOException
{
encode(getTag(), ostream);
}
/**
* Writes the DER encoding to the given output stream,
* using the given implicit tag. To satisfy DER encoding rules,
* the elements will be re-ordered either by tag or lexicographically.
*/
public void encode(Tag implicitTag, OutputStream ostream)
throws IOException
{
// what ordering method?
boolean lexOrdering;
if( elements.size() < 2 ) {
// doesn't matter, only one element
lexOrdering = true;
} else if( tagAt(0).equals(tagAt(1)) ) {
// tags are the same, lexicographic ordering
lexOrdering = true;
} else {
// tags are different, order by tag
lexOrdering = false;
}
// compute and order contents
int numElements = elements.size();
int totalBytes = 0;
Vector encodings = new Vector(numElements);
Vector tags = new Vector(numElements);
int i;
for(i = 0; i < numElements; i++ ) {
// if an entry is null, just skip it
if( elementAt(i) != null ) {
byte[] enc = ASN1Util.encode(tagAt(i), elementAt(i));
totalBytes += enc.length;
if( lexOrdering ) {
insertInOrder(encodings, enc);
} else {
insertInOrder(encodings, enc, tags, (int) tagAt(i).getNum());
}
}
}
// write header
ASN1Header header = new ASN1Header( implicitTag, FORM, totalBytes );
header.encode(ostream);
// write contents in order
for(i=0; i < numElements; i++ ) {
ostream.write( (byte[]) encodings.elementAt(i) );
}
}
/**
* Encodes this SET without re-ordering it. This may violate
* DER, but it is within BER.
*/
public void BERencode(Tag implicitTag, OutputStream ostream)
throws IOException
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// compute contents
int size = elements.size();
for(int i = 0; i < size; i++ ) {
ASN1Value el = elementAt(i);
if(el!=null) {
el.encode(tagAt(i), bos);
}
}
byte[] bytes = bos.toByteArray();
// write header
ASN1Header header = new ASN1Header( implicitTag, FORM, bytes.length );
header.encode(ostream);
// write contents
ostream.write(bytes);
}
// performs ascending lexicographic ordering
// linear search, but number of items is usually going to be small.
private static void insertInOrder(Vector encs, byte[] enc) {
int size = encs.size();
// find the lowest item that we are less than or equal to
int i;
for(i=0; i < size; i++) {
if( compare(enc, (byte[])encs.elementAt(i)) < 1 ) {
break;
}
}
// insert ourself before this item
encs.insertElementAt(enc, i);
}
// performs ascending ordering by tag
// linear search, but number of items is usually going to be small.
private static void insertInOrder(Vector encs, byte[] enc, Vector tags,
int tag)
{
int size = encs.size();
// find the lowest item that we are less than or equal to
int i;
for(i = 0; i < size; i++) {
if( tag <= ((Integer)tags.elementAt(i)).intValue() ) {
break;
}
}
// insert ourself before this item
encs.insertElementAt(enc, i);
tags.insertElementAt(new Integer(i), i );
}
// compares two byte arrays
// returns 1 if left > right, -1 if left < right, 0 if left == right
private static int compare(byte[] left, byte[] right) {
int min = (left.length < right.length) ? left.length : right.length;
for(int i=0; i < min; i++) {
if( (left[i]&0xff) < (right[i]&0xff) ) {
return -1;
} else if( (left[i]&0xff) > (right[i]&0xff) ) {
return 1;
}
}
// equal up to the minimal endpoint
if( left.length > min ) {
Assert._assert(right.length==min);
return 1;
}
if( right.length > min ) {
Assert._assert(left.length==min);
return -1;
}
return 0;
}
/**
* An element of a SET
*/
static class Element {
/**
* Makes a new SET element from the given value.
*/
public Element( ASN1Value val ) {
this.val = val;
}
/**
* Makes a new SET element from the given value with the given
* implicit tag.
*/
public Element( Tag implicitTag, ASN1Value val )
{
this.val = val;
this.implicitTag = implicitTag;
}
private ASN1Value val;
/**
* Returns the value of this SET element.
*/
public ASN1Value getValue() {
return val;
}
/**
* Returns the tag that actually shows up in the encoding.
* If there is an implicit tag, it will be used. Otherwise,
* it will be the base tag for the value.
*/
public Tag getTag() {
if(implicitTag!=null) {
return implicitTag;
} else {
return val.getTag();
}
}
private Tag implicitTag=null;
/**
* Returns the implicit tag for this value, if there is one.
* If not, returns null.
*/
public Tag getImplicitTag() {
return implicitTag;
}
}
/**
* SET.Template
* This class is used for decoding DER-encoded SETs.
*/
public static class Template implements ASN1Template {
private Vector elements = new Vector();
private void addElement( Element e ) {
elements.addElement(e);
}
private void insertElementAt( Element e, int index ) {
elements.insertElementAt(e, index);
}
/**
* Adds a sub-template to the end of this SET template. For example,
* if the ASN.1 included:
*
* MySet ::= SET {
* item SubType,
* ... }
*
* the "item" element would be added to the MySet template with:
*
* mySet.addElement( new SubType.Template() );
*
*/
public void addElement( ASN1Template t ) {
addElement( new Element(TAG, t, false) );
}
/**
* Inserts the template at the given index.
*/
public void insertElementAt( ASN1Template t, int index )
{
insertElementAt( new Element(TAG, t, false), index );
}
/**
* Adds a sub-template with the given implicit tag to the end of this
* SET template. For example, if the ASN.1 included:
*
* MySet ::= SET {
* item [0] IMPLICIT SubType,
* ... }
*
* the "item" element would be added to the MySet template with:
*
* mySet.addElement( new Tag(0), new SubType.Template() );
*
*/
public void addElement( Tag implicit, ASN1Template t ) {
addElement( new Element(implicit, t, false) );
}
/**
* Inserts the template with the given implicit tag at the given index.
*/
public void insertElementAt( Tag implicit, ASN1Template t,
int index )
{
insertElementAt( new Element(implicit, t, false), index );
}
/**
* Adds an optional sub-template to the end
* of this SET template. For example, if the ASN.1 included:
*
* MySet ::= SET {
* item SubType OPTIONAL,
* ... }
*
* the "item" element would be added to the MySet template with:
*
* mySet.addOptionalElement( new SubType.Template() );
*
*/
public void addOptionalElement( ASN1Template t ) {
addElement( new Element(TAG, t, true) );
}
/**
* Inserts the optional template at the given index.
*/
public void insertOptionalElementAt( ASN1Template t, int index )
{
insertElementAt( new Element(null, t, true), index );
}
/**
* Adds an optional sub-template with the given implicit tag to the end
* of this SET template. For example, if the ASN.1 included:
*
* MySet ::= SET {
* item [0] IMPLICIT SubType OPTIONAL,
* ... }
*
* the "item" element would be added to the MySet template with:
*
* mySet.addOptionalElement( new Tag(0), new SubType.Template() );
*
*/
public void addOptionalElement( Tag implicit, ASN1Template t ) {
addElement( new Element(implicit, t, true) );
}
/**
* Inserts the optional template with the given default
* value at the given index.
*/
public void insertOptionalElementAt( Tag implicit, ASN1Template t,
int index )
{
insertElementAt( new Element(implicit, t, true), index );
}
/**
* Adds a sub-template with the given default value to the end
* of this SET template. For example, if the ASN.1 included:
*
* MySet ::= SET {
* item INTEGER DEFAULT (5),
* ... }
*
* the "item" element would be added to the MySet template with:
*
* mySet.addElement( new SubType.Template(), new INTEGER(5) );
*
*/
public void addElement( ASN1Template t, ASN1Value def ) {
addElement( new Element(TAG, t, def) );
}
/**
* Inserts the template with the given default
* value at the given index.
*/
public void insertElementAt( ASN1Template t, ASN1Value def, int index )
{
insertElementAt( new Element(null, t, def), index );
}
/**
* Adds a sub-template with the given default value and implicit tag to
* the end of this SET template. For example, if the ASN.1 included:
*
* MySet ::= SET {
* item [0] IMPLICIT INTEGER DEFAULT (5),
* ... }
*
* the "item" element would be added to the MySet template with:
*
* mySet.addElement( new Tag(0), new SubType.Template(), new INTEGER(5) );
*
*/
public void addElement( Tag implicit, ASN1Template t, ASN1Value def ) {
addElement( new Element(implicit, t, def) );
}
/**
* Inserts the template with the given implicit tag and given default
* value at the given index.
*/
public void insertElementAt( Tag implicit, ASN1Template t, ASN1Value def,
int index )
{
insertElementAt( new Element(implicit, t, def), index );
}
/**
* Returns the implicit tag of the item stored at the given index.
* May be NULL if no implicit tag was specified.
*/
public Tag implicitTagAt(int index) {
return ((Element)elements.elementAt(index)).getImplicitTag();
}
/**
* Returns the sub-template stored at the given index.
*/
public ASN1Template templateAt(int index) {
return ((Element)elements.elementAt(index)).getTemplate();
}
/**
* Returns true
if the sub-template at the given index
* is optional.
*/
public boolean isOptionalAt(int index) {
return ((Element)elements.elementAt(index)).isOptional();
}
private boolean isRepeatableAt(int index) {
return ((Element)elements.elementAt(index)).isRepeatable();
}
/**
* Returns the default value for the sub-template at the given index.
* May return NULL if no default value was specified.
*/
public ASN1Value defaultAt(int index) {
return ((Element)elements.elementAt(index)).getDefault();
}
/**
* Returns the number of elements in the SET.
*/
public int size() {
return elements.size();
}
public void removeAllElements() {
elements.removeAllElements();
}
public void removeElementAt(int index) {
elements.removeElementAt(index);
}
private Tag getTag() {
return SET.TAG;
}
/**
* Determines whether the given tag satisfies this template.
*/
public boolean tagMatch(Tag tag) {
return( tag.equals(SET.TAG) );
}
/**
* Decodes the input stream into a SET value.
*/
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
return decode(getTag(), istream);
}
/**
* Decodes the input stream into a SET value with the given implicit
* tag.
*/
public ASN1Value decode(Tag tag, InputStream istream)
throws IOException, InvalidBERException
{
try {
ASN1Header header = new ASN1Header(istream);
header.validate( tag, Form.CONSTRUCTED );
// remainingContent will be -1 for indefinite length encoding
long remainingContent = header.getContentLength();
SET set = new SET();
ASN1Header lookAhead;
boolean[] found = new boolean[ elements.size() ];
// while content remains, try to decode it
while( remainingContent > 0 || remainingContent == -1) {
// find out about the next item
lookAhead = ASN1Header.lookAhead(istream);
// if we found the end-of-content marker, we're done
if( lookAhead.isEOC() ) {
if( remainingContent != -1 ) {
throw new InvalidBERException("Unexpected end-of-content"+
"marker");
}
lookAhead = new ASN1Header(istream);
break;
}
// Find the element with the matching tag
int index = findElementByTag( lookAhead.getTag() );
if( index == -1 ) {
// element not found
throw new InvalidBERException("Unexpected Tag in SET: "+
lookAhead.getTag() );
}
Element e = (Element) elements.elementAt(index);
if( found[index] && ! e.isRepeatable() ) {
// element already found, and it's not repeatable
throw new InvalidBERException("Duplicate Tag in SET: "+
lookAhead.getTag() );
}
// mark this element as found
found[index] = true;
// Decode this element
ASN1Template t = e.getTemplate();
ASN1Value val;
CountingStream countstream = new CountingStream(istream);
if( e.getImplicitTag() == null ) {
val = t.decode(countstream);
} else {
val = t.decode(e.getImplicitTag(), countstream);
}
// Decrement remaining count
long len = countstream.getNumRead();
if( remainingContent != -1 ) {
if( remainingContent < len ) {
// this item went past the end of the SET
throw new InvalidBERException("Item went "+
(len-remainingContent)+" bytes past the end of"+
" the SET");
}
remainingContent -= len;
}
// Store this element in the SET
SET.Element se;
if( e.getImplicitTag() == null ) {
// no implicit tag
se = new SET.Element(val);
} else {
// there is an implicit tag
se = new SET.Element( e.getImplicitTag(), val );
}
set.addElement(se);
}
// We check for this after we read in each item, so this shouldn't
// happen
Assert._assert( remainingContent == 0 || remainingContent == -1);
// Deal with elements that weren't present.
int size = elements.size();
for(int i = 0; i < size; i++) {
if( !found[i] ) {
if( isOptionalAt(i) || isRepeatableAt(i) ) {
// no problem
} else if( defaultAt(i) != null ) {
set.addElement( new SET.Element(defaultAt(i)) );
} else {
throw new InvalidBERException("Field not found in SET");
}
}
}
return set;
} catch(InvalidBERException e) {
throw new InvalidBERException(e, "SET");
}
}
/**
* Returns the index in the vector of the type with this tag and class,
* or -1 if not found.
* lame linear search - but we're dealing with small numbers of elements,
* so it's probably not worth it to use a hashtable
*/
private int findElementByTag(Tag tag) {
int size = elements.size();
for( int i = 0; i < size ; i++ ) {
Element e = (Element) elements.elementAt(i);
if( e.tagMatch( tag ) ) {
// match!
return i;
}
}
// no match
return -1;
}
/**
* An element of a SET template.
*/
public static class Element {
public Element(Tag implicitTag, ASN1Template type, boolean optional)
{
this.type = type;
defaultVal = null;
this.optional = optional;
this.implicitTag = implicitTag;
}
public Element(Tag implicitTag, ASN1Template type, ASN1Value defaultVal)
{
this.type = type;
this.defaultVal = defaultVal;
optional = false;
this.implicitTag = implicitTag;
}
// Repeatability is used for SET OF. It is package private.
private boolean repeatable;
void makeRepeatable() {
repeatable = true;
}
boolean isRepeatable() {
return repeatable;
}
private boolean optional;
public boolean isOptional() {
return optional;
}
private Tag implicitTag=null;
public Tag getImplicitTag() {
return implicitTag;
}
/**
* Determines whether the given tag satisfies this SET element.
*/
public boolean tagMatch(Tag tag) {
if( implicitTag != null ) {
return( implicitTag.equals(tag) );
} else {
return type.tagMatch(tag);
}
}
private ASN1Template type;
/**
* Returns the template for this element.
*/
public ASN1Template getTemplate() {
return type;
}
private ASN1Value defaultVal=null;
/**
* Returns the default value for this element, if one exists.
* Otherwise, returns null.
*/
public ASN1Value getDefault() {
return defaultVal;
}
}
} // End of SET.Template
/**
* A Template for decoding SET OF values.
* Use this if you have a SIZE qualifier on your SET OF.
* The SET will consume as many instances of type as it can, rather than
* stopping after the first one. This is equivalent to SIZE (0..MAX).
* If you need something more restrictive, you can look at what gets parsed
* and decide whether it's OK or not yourself.
*/
public static class OF_Template implements ASN1Template {
private OF_Template() { }
private Template template; // a normal SET template
/**
* Creates an OF_Template with the given type. For example:
*
* MySet ::= SET OF INTEGER;
*
* A MySet
template would be constructed with:
*
* SET.OF_Template mySetTemplate = new SET.OF_Template( new
* INTEGER.Template() );
*
*/
public OF_Template(ASN1Template type) {
template = new Template();
Template.Element el = new Template.Element( null, type, false );
el.makeRepeatable();
template.addElement( el );
}
public boolean tagMatch(Tag tag) {
return TAG.equals(tag);
}
/**
* Decodes a SET OF
from its BER encoding.
*/
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
return template.decode(istream);
}
/**
* Decodes a SET OF
with an implicit tag from its BER
* encoding.
*/
public ASN1Value decode(Tag implicitTag, InputStream istream)
throws IOException, InvalidBERException
{
return template.decode(implicitTag, istream);
}
}
// Test driver for SET
public static void main(String args[]) {
try {
if(args.length > 0) {
FileInputStream fin = new FileInputStream( args[0] );
Template t = new SET.Template();
t.addElement(new Tag(0), new INTEGER.Template() );
t.addElement( new Tag(3), new INTEGER.Template() );
t.addOptionalElement( new Tag(4), new INTEGER.Template() );
t.addElement( new Tag(5), new INTEGER.Template(), new INTEGER(67) );
t.addElement( new Tag(29), new BOOLEAN.Template() );
t.addElement( new Tag(30), new BOOLEAN.Template(), new BOOLEAN(false) );
t.addElement( new Tag(1), new INTEGER.Template() );
t.addElement( new Tag(2), new INTEGER.Template() );
SET st = (SET) t.decode(new BufferedInputStream(fin) );
for(int i=0; i < st.size(); i++) {
ASN1Value v = st.elementAt(i);
if( v instanceof INTEGER ) {
INTEGER in = (INTEGER) st.elementAt(i);
System.out.println("INTEGER: "+in);
} else if( v instanceof BOOLEAN ) {
BOOLEAN bo = (BOOLEAN) st.elementAt(i);
System.out.println("BOOLEAN: "+bo);
} else {
System.out.println("Unknown value");
}
}
} else {
SET s = new SET();
s.addElement( new Tag(0), new INTEGER(255) );
s.addElement( new Tag(29), new BOOLEAN(true) );
s.addElement( new Tag(1), new INTEGER(-322) );
s.addElement( new Tag(2), new INTEGER(0) );
s.addElement( new Tag(3), new INTEGER("623423948273") );
s.encode(System.out);
}
} catch( Exception e ) {
e.printStackTrace();
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/Tag.java 0000664 0000000 0000000 00000011532 13261450000 0020366 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.math.BigInteger;
/**
* Represents an ASN.1 Tag. A tag consists of a class and a number.
*/
public class Tag {
private long num;
/**
* Returns the tag number.
*/
public long getNum() {
return num;
}
private Class tClass;
/**
* Returns the tag class.
*/
public Class getTagClass() {
return tClass;
}
private Tag() { }
/**
* A tag class.
*/
public static final Class UNIVERSAL = Class.UNIVERSAL;
/**
* A tag class.
*/
public static final Class APPLICATION = Class.APPLICATION;
/**
* A tag class.
*/
public static final Class CONTEXT_SPECIFIC = Class.CONTEXT_SPECIFIC;
/**
* A tag class.
*/
public static final Class PRIVATE = Class.PRIVATE;
/**
* The end-of-contents marker for indefinite length encoding.
* It is encoded the same as an ASN.1 header whose tag is [UNIVERSAL 0].
*/
public static final Tag END_OF_CONTENTS = new Tag( UNIVERSAL, 0 );
/**
* An alias for END_OF_CONTENTS.
*/
public static final Tag EOC = END_OF_CONTENTS;
/**
* Creates a tag with the given class and number.
* @param clazz The class of the tag.
* @param num The tag number.
*/
public Tag(Class clazz, long num) {
tClass = clazz;
this.num = num;
}
/**
* Creates a CONTEXT-SPECIFIC tag with the given tag number.
* @param num The tag number.
*/
public Tag(long num) {
this(Class.CONTEXT_SPECIFIC, num);
}
///////////////////////////////////////////////////////////////////////
// Tag Instances
//
// Since grabbing a context-specific tag is a very common operation,
// let's make singletons of the most frequently used tags.
///////////////////////////////////////////////////////////////////////
private static final int numTagInstances = 10;
private static Tag tagInstances[] = new Tag[numTagInstances];
static {
for(int i=0; i < numTagInstances; i++) {
tagInstances[i] = new Tag(i);
}
}
/**
* Returns an instance of a context-specific tag with the given number.
* The returned instance may be singleton. It is usually more efficient to
* call this method than create your own context-specific tag.
*/
public static Tag get(long num) {
if( num >= 0 && num < numTagInstances ) {
return tagInstances[(int)num];
} else {
return new Tag(num);
}
}
public int hashCode() {
return (tClass.toInt() * 131) + (int)num;
}
/**
* Compares two tags for equality. Tags are equal if they have
* the same class and tag number.
*/
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(! (obj instanceof Tag) ) {
return false;
}
Tag t = (Tag) obj;
if( num == t.num && tClass == t.tClass ) {
return true;
} else {
return false;
}
}
/**
* Returns a String representation of the tag. For example, a tag
* whose class was UNIVERSAL and whose number was 16 would return
* "UNIVERSAL 16".
*/
public String toString() {
return tClass+" "+num;
}
/**
* An enumeration of the ASN.1 tag classes.
*/
public static class Class {
private Class() { }
private Class(int enc, String name) {
encoding = enc;
this.name = name;
}
private int encoding;
private String name;
public static final Class UNIVERSAL = new Class(0, "UNIVERSAL");
public static final Class APPLICATION = new Class(1, "APPLICATION");
public static final Class CONTEXT_SPECIFIC =
new Class(2, "CONTEXT-SPECIFIC");
public static final Class PRIVATE = new Class(3, "PRIVATE");
public int toInt() {
return encoding;
}
public String toString() {
return name;
}
/**
* @exception InvalidBERException If the given int does not correspond
* to any tag class.
*/
public static Class fromInt(int i) throws InvalidBERException {
if( i == 0 ) {
return UNIVERSAL;
} else if(i == 1) {
return APPLICATION;
} else if(i == 2) {
return CONTEXT_SPECIFIC;
} else if(i == 3) {
return PRIVATE;
} else {
throw new InvalidBERException("Invalid tag class: " + i);
}
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/TeletexString.java 0000664 0000000 0000000 00000005057 13261450000 0022461 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.CharConversionException;
/**
* The ASN.1 type TeletexString.
*/
public class TeletexString extends CharacterString implements ASN1Value {
public static final Tag TAG = new Tag(Tag.UNIVERSAL, 20);
public Tag getTag() {
return TAG;
}
public TeletexString(char[] chars) throws CharConversionException {
super(chars);
}
public TeletexString(String s) throws CharConversionException {
super(s);
}
CharConverter getCharConverter() {
return new TeletexConverter();
}
/**
* Returns a singleton instance of the decoding template for this class.
*/
public static Template getTemplate() {
return templateInstance;
}
private static final Template templateInstance = new Template();
// nested class
public static class Template
extends CharacterString.Template implements ASN1Template
{
protected Tag getTag() {
return TAG;
}
public boolean tagMatch(Tag tag) {
return TAG.equals(tag);
}
protected CharConverter getCharConverter() {
return new TeletexConverter();
}
protected CharacterString generateInstance(char[] bytes)
throws CharConversionException
{
return new TeletexString( bytes );
}
protected String typeName() {
return "TeletexString";
}
} // end of Template
private static class TeletexConverter implements CharConverter {
public char[] byteToChar(byte[] bytes, int offset, int len)
throws CharConversionException
{
char[] chars = new char[len];
int b;
int c;
for(b=offset, c=0; c < len; b++, c++) {
chars[c] = (char) (bytes[b] & 0xff);
}
return chars;
}
public byte[] charToByte(char[] chars, int offset, int len)
throws CharConversionException
{
byte[] bytes = new byte[len];
int b;
int c;
for(b=0, c=offset; b < len; b++, c++) {
if( (chars[c]&0xff00) != 0 ) {
throw new CharConversionException("Invalid character for"+
" TeletexString");
}
bytes[b] = (byte) (chars[c] & 0xff);
}
return bytes;
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/TimeBase.java 0000664 0000000 0000000 00000023001 13261450000 0021336 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import org.mozilla.jss.util.Assert;
public abstract class TimeBase implements ASN1Value {
public static final Form FORM = Form.PRIMITIVE;
abstract public Tag getTag();
private Date date;
public Date toDate() {
return date;
}
abstract protected boolean isUTC();
private TimeBase() { }
public TimeBase(Date date) {
this.date = date;
}
public void encode(OutputStream ostream) throws IOException {
encode(getTag(), ostream);
}
/**
* Write the DER-encoding of this TimeBase.
*/
public void encode(Tag implicit, OutputStream ostream) throws IOException {
if( isUTC() ) {
// length will always be 13
(new ASN1Header(implicit, FORM, 13)).encode(ostream);
} else {
// length will always be 15
(new ASN1Header(implicit, FORM, 15)).encode(ostream);
}
int i=0, val;
// DER-encoding mandates GMT time zone
Calendar cal = Calendar.getInstance( TimeZone.getTimeZone("GMT") );
cal.setTime( date );
if( isUTC() ) {
val = cal.get(Calendar.YEAR);
ostream.write( ((val % 100) / 10) + '0' );
ostream.write( (val % 10) + '0' );
} else {
val = cal.get(Calendar.YEAR);
ostream.write( ((val % 10000) / 1000) + '0' );
ostream.write( ((val % 1000) / 100) + '0' );
ostream.write( ((val % 100) / 10) + '0' );
ostream.write( (val % 10) + '0' );
}
val = cal.get(Calendar.MONTH) + 1;
Assert._assert( val >= 1 && val <= 12 );
ostream.write( (val / 10) + '0' );
ostream.write( (val % 10) + '0' );
val = cal.get(Calendar.DAY_OF_MONTH);
Assert._assert( val >=1 && val <= 31 );
ostream.write( (val / 10) + '0' );
ostream.write( (val % 10) + '0' );
val = cal.get(Calendar.HOUR_OF_DAY);
Assert._assert( val >= 0 && val <= 23 );
ostream.write( (val / 10) + '0' );
ostream.write( (val % 10) + '0' );
val = cal.get(Calendar.MINUTE);
Assert._assert( val >=0 && val <= 59 );
ostream.write( (val / 10) + '0' );
ostream.write( (val % 10) + '0' );
val = cal.get(Calendar.SECOND);
Assert._assert( val >= 0 && val <= 59 );
ostream.write( (val / 10) + '0' );
ostream.write( (val % 10) + '0' );
ostream.write('Z');
}
public abstract static class Template {
protected abstract boolean isUTC();
protected abstract Tag getTag();
protected abstract TimeBase generateInstance(Date date);
public boolean tagMatch(Tag tag) {
return getTag().equals(tag);
}
public ASN1Value decode(InputStream istream)
throws IOException, InvalidBERException
{
return decode(getTag(), istream);
}
public ASN1Value decode(Tag implicitTag, InputStream istream)
throws IOException, InvalidBERException
{
PrintableString.Template pst = new PrintableString.Template();
PrintableString ps = (PrintableString)
pst.decode(implicitTag, istream);
char[] chars = ps.toCharArray();
int i=0;
int year, month, day, hour, minute, second, hourOff, minOff;
//////////////////////////////////////////
// Get year
//
if( isUTC() ) {
checkBounds(i, 2, chars.length);
year = (chars[i] - '0') * 10;
year += chars[i+1] - '0';
// Y2K HACK!!!!! But this is what the spec says to do.
// The range is 1970 to 2069
if( year < 70 ) {
year += 2000;
} else {
year += 1900;
}
i += 2;
} else {
checkBounds(i, 4, chars.length);
year = (chars[i] - '0') * 1000;
year += (chars[i+1] - '0') * 100;
year += (chars[i+2] - '0') * 10;
year += (chars[i+3] - '0');
checkRange(year, 0, 9999, "year");
i += 4;
}
//////////////////////////////////////////
// get month
//
month = 0;
checkBounds(i, 2, chars.length);
month = (chars[i] - '0') * 10;
month += chars[i+1] - '0';
checkRange(month, 1, 12, "month");
month--; // Java months start at 0
i += 2;
//////////////////////////////////////////
// get day
//
checkBounds(i, 2, chars.length);
day = (chars[i] - '0') * 10;
day += chars[i+1] - '0';
checkRange(day, 1, 31, "day");
i += 2;
//////////////////////////////////////////
// get hour
//
checkBounds(i, 2, chars.length);
hour = (chars[i] - '0') * 10;
hour += chars[i+1] - '0';
checkRange(hour, 0, 23, "hour");
i += 2;
//////////////////////////////////////////
// get minute
//
checkBounds(i, 2, chars.length);
minute = (chars[i] - '0') * 10;
minute += chars[i+1] - '0';
checkRange(minute, 0, 59, "minute");
i += 2;
//////////////////////////////////////////
// get second, if it's there
//
if( i < chars.length && chars[i] >= '0' && chars[i] <= '9' ) {
checkBounds(i, 2, chars.length);
second = (chars[i] - '0') * 10;
second += chars[i+1] - '0';
checkRange(second, 0, 59, "second");
i += 2;
} else {
second = 0;
}
//////////////////////////////////////////
// Skip milliseconds for GeneralizedTime. There are no
// milliseconds in UTCTime.
//
if( ! isUTC() ) {
while( i < chars.length &&
chars[i] != '+' &&
chars[i] != '-' &&
chars[i] != 'Z' )
{
i++;
}
}
//////////////////////////////////////////
// get time zone
//
TimeZone tz;
if( i < chars.length ) {
checkBounds(i, 1, chars.length);
if( chars[i] == '+' || chars[i] == '-') {
checkBounds(i+1, 4, chars.length);
hourOff = (chars[i+1] - '0') * 10;
hourOff += chars[i+2] - '0';
minOff = (chars[i+3] - '0') * 10;
minOff += chars[i+4] - '0';
checkRange(hourOff, 0, 23, "hour offset");
checkRange(minOff, 0, 59, "minute offset");
if( chars[i] == '-' ) {
hourOff = -hourOff;
minOff = -minOff;
}
i += 5;
tz = (TimeZone) TimeZone.getTimeZone("GMT").clone();
tz.setRawOffset( ((hourOff*60)+minOff)*60*1000 );
} else if( chars[i] == 'Z' ) {
i += 1;
hourOff = minOff = 0;
tz = (TimeZone) TimeZone.getTimeZone("GMT").clone();
} else {
throw new InvalidBERException("Invalid character "+
chars[i]);
}
} else {
if( isUTC() ) {
// Only UTC requires timezone
throw new InvalidBERException("no timezone specified for"+
" UTCTime");
}
// No timezone specified, use local time.
// This is generally a bad idea, because who knows what the
// local timezone is? But the spec allows it.
tz = TimeZone.getDefault();
}
// make sure we ate all the characters, there were no stragglers
// at the end
if( i != chars.length ) {
throw new InvalidBERException("Extra characters at end");
}
// Create a calendar object from the date and time zone.
Calendar cal = Calendar.getInstance( tz );
cal.set(year, month, day, hour, minute, second);
return generateInstance(cal.getTime());
}
private static void
checkRange(int val, int low, int high, String field)
throws InvalidBERException
{
if( val < low || val > high ) {
throw new InvalidBERException("Invalid "+field);
}
}
private static void
checkBounds(int index, int increment, int bound)
throws InvalidBERException
{
if(index+increment > bound) {
throw new InvalidBERException("Too few characters in " +
"TimeBase");
}
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/UTCTime.java 0000664 0000000 0000000 00000002341 13261450000 0021123 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.IOException;
import java.util.Date;
public class UTCTime extends TimeBase implements ASN1Value {
public static final Tag TAG = new Tag(Tag.UNIVERSAL, 23);
public Tag getTag() {
return TAG;
}
public UTCTime(Date date) {
super(date);
}
protected boolean isUTC() {
return true;
}
private static final UTCTime.Template templateInstance =
new UTCTime.Template();
public static UTCTime.Template getTemplate() {
return templateInstance;
}
public static class Template extends TimeBase.Template
implements ASN1Template
{
protected Tag getTag() {
return TAG;
}
public boolean tagMatch(Tag tag) {
return TAG.equals(tag);
}
protected boolean isUTC() {
return true;
}
protected TimeBase generateInstance(Date date) {
return new UTCTime(date);
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/UTF8String.java 0000664 0000000 0000000 00000005225 13261450000 0021572 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.CharConversionException;
import java.io.UnsupportedEncodingException;
import org.mozilla.jss.util.Assert;
public class UTF8String extends CharacterString implements ASN1Value {
public UTF8String(char[] chars) throws CharConversionException {
super(chars);
}
public UTF8String(String s) throws CharConversionException {
super(s);
}
CharConverter getCharConverter() {
return new UTF8Converter();
}
public static final Tag TAG = new Tag( Tag.UNIVERSAL, 12 );
public static final Form FORM = Form.PRIMITIVE;
public Tag getTag() {
return TAG;
}
private static final Template templateInstance = new Template();
/**
* Returns a singleton instance of UTF8String.Template. This is more
* efficient than creating a new UTF8String.Template.
*/
public static Template getTemplate() {
return templateInstance;
}
// nested class
public static class Template
extends CharacterString.Template implements ASN1Template
{
protected Tag getTag() {
return TAG;
}
public boolean tagMatch(Tag tag) {
return TAG.equals(tag);
}
protected CharConverter getCharConverter() {
return new UTF8Converter();
}
protected CharacterString generateInstance(char[] chars)
throws CharConversionException
{
return new UTF8String(chars);
}
protected String typeName() {
return "UTF8String";
}
}
private static class UTF8Converter implements CharConverter {
public char[] byteToChar(byte[] bytes, int offset, int len)
throws CharConversionException
{
try {
String s = new String(bytes, offset, len, "UTF8");
return s.toCharArray();
} catch( UnsupportedEncodingException e ) {
String err = "Unable to find UTF8 encoding mechanism";
Assert.notReached(err);
throw new CharConversionException(err);
}
}
public byte[] charToByte(char[] chars, int offset, int len)
throws CharConversionException
{
try {
String s = new String(chars, offset, len);
return s.getBytes("UTF8");
} catch( UnsupportedEncodingException e ) {
String err = "Unable to find UTF8 encoding mechanism";
Assert.notReached(err);
throw new CharConversionException(err);
}
}
} // end of char converter
}
jss-4.4.3/jss/org/mozilla/jss/asn1/UniversalString.java 0000664 0000000 0000000 00000015206 13261450000 0023014 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.asn1;
import java.io.CharConversionException;
import java.io.CharArrayWriter;
import java.io.ByteArrayOutputStream;
/**
* A UCS4 string.
*/
public class UniversalString extends CharacterString implements ASN1Value {
public static final Tag TAG = new Tag(Tag.UNIVERSAL, 28);
public Tag getTag() {
return TAG;
}
public UniversalString(char[] chars) throws CharConversionException {
super(chars);
}
public UniversalString(String s) throws CharConversionException {
super(s);
}
CharConverter getCharConverter() {
return new UniversalConverter();
}
/**
* Returns a singleton instance of the decoding template for this class.
*/
public static Template getTemplate() {
return templateInstance;
}
private static final Template templateInstance = new Template();
// nested class
public static class Template
extends CharacterString.Template implements ASN1Template
{
protected Tag getTag() {
return TAG;
}
public boolean tagMatch(Tag tag) {
return TAG.equals(tag);
}
protected CharConverter getCharConverter() {
return new UniversalConverter();
}
protected CharacterString generateInstance(char[] chars)
throws CharConversionException
{
return new UniversalString( chars );
}
protected String typeName() {
return "UniversalString";
}
} // end of Template
/**
* A class for converting between Unicode and UCS4.
*/
private static class UniversalConverter implements CharConverter {
// This is the maximum a UCS4 character can be if it has
// straight Unicode inside it.
public static final int MAX_UNICODE = 0x0000ffff;
// This is the maximum a UCS4 character can be if it is UTF-16
// encoded. UTF-16 encoding allows UCS4 chars to be stored across
// two Unicode chars.
public static final int MAX_UTF16 = 0x0010ffff;
// This Unicode character is used to represent an unknown character
// in some other encoding. We use it for UCS4 characters that
// are not a part of normal Unicode and also cannot be encoded
// across two Unicode chars with UTF-16.
public static final char REPLACEMENT_CHAR = 0xfffd;
// This is the base for UCS4 characters that can be mapped with UTF16.
public static final int UTF16_BASE = 0x00100000;
// In UTF16 encoding, each Unicode character has 10 bits of
// information.
public static final int HALF_SHIFT = 10;
// The lowest 10 bits
public static final int HALF_MASK = 0x3ff;
public static final int UTF16_HIGH_START = 0xd800;
public static final int UTF16_HIGH_END = 0xdcff;
public static final int UTF16_LOW_START = 0xdc00;
public static final int UTF16_LOW_END = 0xdfff;
/**
* Turns big-endian UCS4 characters into Unicode Java characters
*/
public char[] byteToChar(byte[] bytes, int offset, int len)
throws CharConversionException
{
// Each UCS4 character is 4 bytes. Most UCS4 characters will
// map to one Unicode character. The exception is UTF-16
// characters, which map to two Unicode characters.
CharArrayWriter out = new CharArrayWriter( len / 4 );
int end = offset + len;
while( offset < end ) {
// eat 4 bytes and make a UCS4 char
if( end - offset < 4 ) {
throw new CharConversionException("input exhausted");
}
int ucs4 = (bytes[offset++] & 0xff) << 24;
ucs4 += (bytes[offset++] & 0xff) << 16;
ucs4 += (bytes[offset++] & 0xff) << 8;
ucs4 += bytes[offset++] & 0xff;
// convert UCS4 to Unicode
if( ucs4 <= MAX_UNICODE ) {
// Unicode is a subset of UCS4, and this char is
// in the common subset. Just chop off the unused top
// two bytes.
out.write( ucs4 & 0xffff );
} else if( ucs4 <= MAX_UTF16 ) {
// This UCS4 char is not in Unicode, but can be encoded
// into two Unicode chars using UTF16.
ucs4 -= UTF16_BASE;
out.write( (ucs4 >>> HALF_SHIFT) + UTF16_HIGH_START );
out.write( (ucs4 & HALF_MASK) + UTF16_LOW_START );
} else {
// This character is not in Unicode or UTF16. We can't
// provide a suitable translation, so use the Unicode
// replacement char.
out.write( REPLACEMENT_CHAR );
}
}
return out.toCharArray();
}
// Convert Unicode chars to UCS4 chars
public byte[] charToByte(char[] chars, int offset, int len)
throws CharConversionException
{
ByteArrayOutputStream out = new ByteArrayOutputStream(len * 4);
int end = offset + len;
while( offset < end ) {
char c = chars[offset++];
int ucs4;
if( c >= UTF16_HIGH_START && c <= UTF16_HIGH_END ) {
// This is the beginning of a UTF16 char
if( offset == end ) {
throw new CharConversionException("input exhausted");
}
char low = chars[offset++];
// make sure the next char is the low half of a UTF16 char
if( low < UTF16_LOW_START || low > UTF16_LOW_END ) {
throw new CharConversionException("UTF16 high "+
"character not followed by a UTF16 low character");
}
ucs4 = UTF16_BASE;
ucs4 += (c - UTF16_HIGH_START) << HALF_SHIFT;
ucs4 += low - UTF16_LOW_START;
} else {
// this is a normal Unicode char
ucs4 = (c & 0x0000ffff);
}
out.write( (ucs4 & 0xff000000) >>> 24 );
out.write( (ucs4 & 0x00ff0000) >>> 16 );
out.write( (ucs4 & 0x0000ff00) >>> 8 );
out.write( (ucs4 & 0x000000ff) );
}
return out.toByteArray();
}
}
}
jss-4.4.3/jss/org/mozilla/jss/asn1/config.mk 0000664 0000000 0000000 00000000415 13261450000 0020604 0 ustar 00root root 0000000 0000000 # This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
TARGETS=$(LIBRARY)
SHARED_LIBRARY=
IMPORT_LIBRARY=
NO_MD_RELEASE = 1
jss-4.4.3/jss/org/mozilla/jss/asn1/manifest.mn 0000664 0000000 0000000 00000007572 13261450000 0021163 0 ustar 00root root 0000000 0000000 #
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
CORE_DEPTH = ../../../..
MODULE = jss
NS_USE_JDK = 1
REQUIRES = nspr20 nss
PACKAGE = org/mozilla/jss/asn1
CLASSES = \
ANY \
ASN1Header \
ASN1Template \
ASN1Util \
ASN1Value \
BIT_STRING \
BMPString \
BOOLEAN \
CharacterString \
CharConverter \
CHOICE \
CountingStream \
ENUMERATED \
EXPLICIT \
FieldNotPresentException \
Form \
GeneralizedTime \
IA5String \
INTEGER \
InvalidBERException \
NULL \
OBJECT_IDENTIFIER \
OCTET_STRING \
PrintableString \
SEQUENCE \
SET \
Tag \
TeletexString \
TimeBase \
UniversalString \
UTCTime \
UTF8String \
$(NULL)
JSRCS = \
ANY.java \
ASN1Header.java \
ASN1Template.java \
ASN1Util.java \
ASN1Value.java \
BIT_STRING.java \
BMPString.java \
BOOLEAN.java \
CharacterString.java \
CharConverter.java \
CHOICE.java \
CountingStream.java \
ENUMERATED.java \
EXPLICIT.java \
FieldNotPresentException.java \
Form.java \
GeneralizedTime.java \
IA5String.java \
INTEGER.java \
InvalidBERException.java \
NULL.java \
OBJECT_IDENTIFIER.java \
OCTET_STRING.java \
PrintableString.java \
SEQUENCE.java \
SET.java \
Tag.java \
TeletexString.java \
TimeBase.java \
UniversalString.java \
UTCTime.java \
UTF8String.java \
$(NULL)
CSRCS = \
ASN1Util.c \
$(NULL)
LIBRARY_NAME = jssasn1
jss-4.4.3/jss/org/mozilla/jss/asn1/package.html 0000664 0000000 0000000 00000000444 13261450000 0021271 0 ustar 00root root 0000000 0000000
ASN.1 structures, BER decoding, and DER encoding.
jss-4.4.3/jss/org/mozilla/jss/config.mk 0000664 0000000 0000000 00000000416 13261450000 0017743 0 ustar 00root root 0000000 0000000 #
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
TARGETS=$(LIBRARY)
SHARED_LIBRARY=
IMPORT_LIBRARY=
NO_MD_RELEASE=1
jss-4.4.3/jss/org/mozilla/jss/crypto/ 0000775 0000000 0000000 00000000000 13261450000 0017464 5 ustar 00root root 0000000 0000000 jss-4.4.3/jss/org/mozilla/jss/crypto/Algorithm.c 0000664 0000000 0000000 00000020740 13261450000 0021561 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include null
if this algorithm does not take any parameters.
* If the algorithm can accept more than one type of parameter,
* this method returns only one of them. It is better to call
* getParameterClasses().
* @deprecated Call getParameterClasses() instead.
*/
public Class getParameterClass() {
if( parameterClasses.length == 0) {
return null;
} else {
return parameterClasses[0];
}
}
/**
* The types of parameter that this algorithm expects. Returns
* null
if this algorithm does not take any parameters.
*/
public Class[] getParameterClasses() {
return (Class[]) parameterClasses.clone();
}
/**
* Returns true if the given Object can be used as a parameter
* for this algorithm.
* update
. Finally,
* doFinal
is called to finalize the operation. Note that
* it is not necessary to call update
if all of the data is
* available at once. In this case, all of the input can be processed with one
* call to doFinal
.
*/
public abstract class Cipher {
/**
* Initializes a encryption context with a symmetric key.
*/
public abstract void initEncrypt(SymmetricKey key)
throws InvalidKeyException, InvalidAlgorithmParameterException,
TokenException;
/**
* Initializes a decryption context with a symmetric key.
*/
public abstract void initDecrypt(SymmetricKey key)
throws InvalidKeyException, InvalidAlgorithmParameterException,
TokenException;
/**
* Initializes an encryption context with a symmetric key and
* algorithm parameters.
*/
public abstract void
initEncrypt(SymmetricKey key, AlgorithmParameterSpec parameters)
throws InvalidKeyException, InvalidAlgorithmParameterException,
TokenException;
/**
* Initializes a decryption context with a symmetric key and
* algorithm parameters.
*/
public abstract void
initDecrypt(SymmetricKey key, AlgorithmParameterSpec parameters)
throws InvalidKeyException, InvalidAlgorithmParameterException,
TokenException;
/**
* Updates the encryption context with additional input.
* @param bytes Bytes of plaintext (if encrypting) or ciphertext (if
* decrypting).
* @return Bytes of ciphertext (if encrypting) or plaintext (if decrypting).
*/
public abstract byte[] update(byte[] bytes)
throws IllegalStateException, TokenException;
/**
* Updates the encryption context with additional plaintext.
* @param bytes Bytes of plaintext (if encrypting) or ciphertext (if
* decrypting).
* @param offset The index in bytes
at which to begin reading.
* @param length The number of bytes from bytes
to read.
* @return Bytes of ciphertext (if encrypting) or plaintext (if decrypting).
*/
public abstract byte[] update(byte[] bytes, int offset, int length)
throws IllegalStateException, TokenException;
/**
* Completes an cipher operation. This can be called directly after
* the context is initialized, or update
may be called
* any number of times before calling final
.
* @param bytes Bytes of plaintext (if encrypting) or ciphertext (if
* decrypting).
* @return The last of the output.
*/
public abstract byte[] doFinal(byte[] bytes)
throws IllegalStateException, IllegalBlockSizeException,
BadPaddingException, TokenException;
/**
* Completes an cipher operation.
* @param bytes Bytes of plaintext (if encrypting) or ciphertext (if
* decrypting).
* @param offset The index in bytes
at which to begin reading.
* @param length The number of bytes from bytes
to read.
* @return The last of the output.
*/
public abstract byte[] doFinal(byte[] bytes, int offset, int length)
throws IllegalStateException, IllegalBlockSizeException,
BadPaddingException, TokenException;
/**
* Completes an cipher operation.
* @return The last of the output.
*/
public abstract byte[] doFinal()
throws IllegalStateException, IllegalBlockSizeException,
BadPaddingException, TokenException;
/**
* Pads a byte array so that its length is a multiple of the given
* blocksize. The method of padding is the one defined in the RSA
* PKCS standards. If M is the length of the data and
* B is the block size, the padding string consists of
* B - (M mod B) octets, each having the value
* B - (M mod B).
* @param toBePadded The byte array to pad.
* @param blockSize The block size of the encryption algorithm. Must be greater
* than zero.
* @see #unPad
*/
public static byte[]
pad(byte[] toBePadded, int blockSize) {
Assert._assert(blockSize > 0);
// the padOctet is also the number of pad octets
byte padOctet = (byte) (blockSize - (toBePadded.length % blockSize));
byte[] padded = new byte[toBePadded.length + padOctet];
System.arraycopy(toBePadded, 0, padded, 0, toBePadded.length);
for(int i = toBePadded.length; i < padded.length; i++) {
padded[i] = padOctet;
}
return padded;
}
/**
* Un-pads a byte array that is padded with PKCS padding.
*
* @param blockSize The block size of the encryption algorithm. This
* is only used for error checking: if the pad size is not
* between 1 and blockSize, a BadPaddingException is thrown.
*
* @see #pad
*/
public static byte[]
unPad(byte[] padded, int blockSize) throws BadPaddingException {
if(padded.length == 0) {
return new byte[0];
}
if( padded.length < blockSize ) {
throw new BadPaddingException("Length of padded array is less than"+
" one block");
}
byte padOctet = padded[padded.length-1];
if(padOctet > blockSize) {
throw new BadPaddingException("Padding octet ("+padOctet+") is "+
"larger than block size ("+blockSize+")");
}
if(padOctet < 1) {
throw new BadPaddingException("Padding octet is less than 1");
}
byte[] unpadded = new byte[padded.length - padOctet];
System.arraycopy(padded, 0, unpadded, 0, unpadded.length);
return unpadded;
}
/**
* Un-pads a byte array that is padded with PKCS padding. Since
* this version does not take block size as a parameter, it cannot
* error check.
* @see #pad
*/
public static byte[]
unPad(byte[] padded) throws BadPaddingException {
if(padded.length == 0) {
return new byte[0];
}
byte padOctet = padded[padded.length-1];
if(padOctet < 1) {
throw new BadPaddingException("Padding octet is less than 1");
} else if(padOctet >= padded.length) {
throw new BadPaddingException("Padding is larger than entire"+
" array");
}
byte[] unpadded = new byte[padded.length - padOctet];
System.arraycopy(padded, 0, unpadded, 0, unpadded.length);
return unpadded;
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/CryptoStore.java 0000664 0000000 0000000 00000013073 13261450000 0022630 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import org.mozilla.jss.CryptoManager;
import org.mozilla.jss.util.*;
import java.security.*;
import java.security.cert.CertificateEncodingException;
import java.io.Serializable;
/**
* This is an interface for a permanent repository of cryptographic objects,
* such as keys, certs, and passwords.
*/
public interface CryptoStore {
////////////////////////////////////////////////////////////
// Private Keys
////////////////////////////////////////////////////////////
/**
* Imports a raw private key into this token (permanently).
*
* @param key The private key.
* @exception TokenException If the key cannot be imported to this token.
* @exception KeyAlreadyImportedException If the key already exists on this token.
*/
public PrivateKey
importPrivateKey( byte[] key,
PrivateKey.Type type )
throws TokenException, KeyAlreadyImportedException;
/**
* Imports a raw private key into this token.
*
* @param key The private key.
* @param temporary Whether the key should be temporary.
* @exception TokenException If the key cannot be imported to this token.
* @exception KeyAlreadyImportedException If the key already exists on this token.
*/
public PrivateKey
importPrivateKey( byte[] key,
PrivateKey.Type type, boolean temporary)
throws TokenException, KeyAlreadyImportedException;
/**
* Returns all private keys stored on this token.
*
* @return An array of all private keys stored on this token.
* @exception TokenException If an error occurs on the token while
* gathering the keys.
*/
public PrivateKey[]
getPrivateKeys() throws TokenException;
/**
* Returns all symmetric keys stored on this token.
*
* @return An array of all symmetric keys stored on this token.
* @exception TokenException If an error occurs on the token while
* gathering the keys.
*/
public SymmetricKey[]
getSymmetricKeys() throws TokenException;
/**
* Deletes the given PrivateKey from the CryptoToken.
* This is a very dangerous call: it deletes the key from the underlying
* token. After calling this, the PrivateKey passed in must no longer
* be used, or a TokenException will occur.
*
* @param key A PrivateKey to be permanently deleted. It must reside
* on this token.
* @exception NoSuchItemOnTokenException If the given private key does
* not reside on this token.
* @exception TokenException If an error occurs on the token while
* deleting the key.
*/
public void deletePrivateKey(org.mozilla.jss.crypto.PrivateKey key)
throws NoSuchItemOnTokenException, TokenException;
/**
* Get an encrypted private key for the given cert.
*
* @param cert Certificate of key to be exported
* @param pbeAlg The PBEAlgorithm to use
* @param pw The password to encrypt with
* @param iteration Iteration count; default of 2000 if le 0
*/
public byte[] getEncryptedPrivateKeyInfo(X509Certificate cert,
PBEAlgorithm pbeAlg, Password pw, int iteration)
throws CryptoManager.NotInitializedException,
ObjectNotFoundException, TokenException;
/**
* Get an encrypted private key, with optional password
* conversion.
*
* @param conv Password converter. If null, pw.getByteCopy()
* will be used to get password bytes.
* @param pw The password
* @param alg The encryption algorithm
* @param n Iteration count; default of 2000 if le 0
* @param k The private key
*/
public byte[] getEncryptedPrivateKeyInfo(
KeyGenerator.CharToByteConverter conv,
Password pw,
Algorithm alg,
int n,
PrivateKey k);
/**
* @param conv Password converter. If null, pw.getByteCopy()
* will be used to get password bytes.
* @param pw The password
* @param nickname Nickname to use for private key
* @param pubKey Public key corresponding to private key
*/
public void importEncryptedPrivateKeyInfo(
KeyGenerator.CharToByteConverter conv,
Password pw,
String nickname,
PublicKey pubKey,
byte[] epkiBytes);
////////////////////////////////////////////////////////////
// Certs
////////////////////////////////////////////////////////////
/**
* Returns all user certificates stored on this token. A user certificate
* is one that has a matching private key.
*
* @return An array of all user certificates present on this token.
* @exception TokenException If an error occurs on the token while
* gathering the certificates.
*/
public X509Certificate[]
getCertificates() throws TokenException;
/**
* Deletes a certificate from a token.
*
* @param cert A certificate to be deleted from this token. The cert
* must actually reside on this token.
* @exception NoSuchItemOnTokenException If the given cert does not
* reside on this token.
* @exception TokenException If an error occurred on the token while
* deleting the certificate.
*/
public void deleteCert(X509Certificate cert)
throws NoSuchItemOnTokenException, TokenException;
}
jss-4.4.3/jss/org/mozilla/jss/crypto/CryptoToken.java 0000664 0000000 0000000 00000025451 13261450000 0022617 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import org.mozilla.jss.util.*;
import java.security.*;
/**
* A CryptoToken performs cryptographic operations and stores
* cryptographic items, such as keys and certs. It corresponds to a
* Cryptographic Service Provider (CSP) in CDSA, and to a PKCS #11 token.
* true
if this algorithm performs padding.
* @deprecated Call getPaddingType() instead.
*/
public boolean isPadded() {
return ! Padding.NONE.equals(padding);
}
/**
* Returns the type of padding for this algorithm.
*/
public Padding getPaddingType() {
return padding;
}
private static Class[] IVParameterSpecClasses = null;
static {
IVParameterSpecClasses = new Class[2];
IVParameterSpecClasses[0] = IVParameterSpec.class;
IVParameterSpecClasses[1] = IvParameterSpec.class;
}
/**
* Returns the number of bytes that this algorithm expects in
* its initialization vector.
*
* @return The size in bytes of the IV for this algorithm. A size of
* 0 means this algorithm does not take an IV.
*/
public native int getIVLength();
public static final EncryptionAlgorithm
RC4 = new EncryptionAlgorithm(SEC_OID_RC4, Alg.RC4, Mode.NONE, Padding.NONE,
(Class)null, 1, OBJECT_IDENTIFIER.RSA_CIPHER.subBranch(4), 0);
public static final EncryptionAlgorithm
DES_ECB = new EncryptionAlgorithm(SEC_OID_DES_ECB, Alg.DES, Mode.ECB,
Padding.NONE, (Class)null, 8, OBJECT_IDENTIFIER.ALGORITHM.subBranch(6),
56);
public static final EncryptionAlgorithm
DES_CBC = new EncryptionAlgorithm(SEC_OID_DES_CBC, Alg.DES, Mode.CBC,
Padding.NONE, IVParameterSpecClasses, 8,
OBJECT_IDENTIFIER.ALGORITHM.subBranch(7), 56);
public static final EncryptionAlgorithm
DES_CBC_PAD = new EncryptionAlgorithm(CKM_DES_CBC_PAD, Alg.DES, Mode.CBC,
Padding.PKCS5, IVParameterSpecClasses, 8, null, 56); // no oid
public static final EncryptionAlgorithm
DES3_ECB = new EncryptionAlgorithm(CKM_DES3_ECB, Alg.DESede, Mode.ECB,
Padding.NONE, (Class)null, 8, null, 168); // no oid
public static final EncryptionAlgorithm
DES3_CBC = new EncryptionAlgorithm(SEC_OID_DES_EDE3_CBC, Alg.DESede,
Mode.CBC, Padding.NONE, IVParameterSpecClasses, 8,
OBJECT_IDENTIFIER.RSA_CIPHER.subBranch(7), 168);
public static final EncryptionAlgorithm
DES3_CBC_PAD = new EncryptionAlgorithm(CKM_DES3_CBC_PAD, Alg.DESede,
Mode.CBC, Padding.PKCS5, IVParameterSpecClasses, 8,
null, 168); //no oid
public static final EncryptionAlgorithm
RC2_CBC = new EncryptionAlgorithm(SEC_OID_RC2_CBC, Alg.RC2, Mode.CBC,
Padding.NONE, RC2ParameterSpec.class, 8,
null, 0); // no oid, see comment below
// Which algorithm should be associated with this OID, RC2_CBC or
// RC2_CBC_PAD? NSS says RC2_CBC, but PKCS #5 v2.0 says RC2_CBC_PAD.
// See NSS bug 202925.
public static final EncryptionAlgorithm
RC2_CBC_PAD = new EncryptionAlgorithm(CKM_RC2_CBC_PAD, Alg.RC2, Mode.CBC,
Padding.PKCS5, RC2ParameterSpec.class, 8,
OBJECT_IDENTIFIER.RSA_CIPHER.subBranch(2), 0);
public static final OBJECT_IDENTIFIER AES_ROOT_OID =
new OBJECT_IDENTIFIER( new long[]
{ 2, 16, 840, 1, 101, 3, 4, 1 } );
public static final EncryptionAlgorithm
AES_128_ECB = new EncryptionAlgorithm(SEC_OID_AES_128_ECB,
Alg.AES, Mode.ECB,
Padding.NONE, (Class)null, 16,
AES_ROOT_OID.subBranch(1), 128);
public static final EncryptionAlgorithm
AES_128_CBC = new EncryptionAlgorithm(SEC_OID_AES_128_CBC,
Alg.AES, Mode.CBC,
Padding.NONE, IVParameterSpecClasses, 16,
AES_ROOT_OID.subBranch(2), 128);
public static final EncryptionAlgorithm
AES_128_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_128_CBC,
Alg.AES, Mode.CBC,
Padding.PKCS5, IVParameterSpecClasses, 16,
AES_ROOT_OID.subBranch(2), 128);
public static final EncryptionAlgorithm
AES_192_ECB = new EncryptionAlgorithm(SEC_OID_AES_192_ECB,
Alg.AES, Mode.ECB,
Padding.NONE, (Class)null, 16, AES_ROOT_OID.subBranch(21), 192);
public static final EncryptionAlgorithm
AES_192_CBC = new EncryptionAlgorithm(SEC_OID_AES_192_CBC,
Alg.AES, Mode.CBC,
Padding.NONE, IVParameterSpecClasses, 16,
AES_ROOT_OID.subBranch(22), 192);
public static final EncryptionAlgorithm
AES_192_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_192_CBC,
Alg.AES, Mode.CBC,
Padding.PKCS5, IVParameterSpecClasses, 16,
AES_ROOT_OID.subBranch(22), 192);
public static final EncryptionAlgorithm
AES_256_ECB = new EncryptionAlgorithm(SEC_OID_AES_256_ECB,
Alg.AES, Mode.ECB,
Padding.NONE, (Class)null, 16, AES_ROOT_OID.subBranch(41), 256);
public static final EncryptionAlgorithm
AES_256_CBC = new EncryptionAlgorithm(SEC_OID_AES_256_CBC,
Alg.AES, Mode.CBC,
Padding.NONE, IVParameterSpecClasses, 16,
AES_ROOT_OID.subBranch(42), 256);
public static final EncryptionAlgorithm
AES_CBC_PAD = new EncryptionAlgorithm(CKM_AES_CBC_PAD, Alg.AES, Mode.CBC,
Padding.PKCS5, IVParameterSpecClasses, 16, null, 256); // no oid
public static final EncryptionAlgorithm
AES_256_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_256_CBC,
Alg.AES, Mode.CBC,
Padding.PKCS5, IVParameterSpecClasses, 16,
AES_ROOT_OID.subBranch(42), 256);
}
jss-4.4.3/jss/org/mozilla/jss/crypto/HMACAlgorithm.java 0000664 0000000 0000000 00000004423 13261450000 0022711 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.util.Hashtable;
import org.mozilla.jss.asn1.*;
import java.security.NoSuchAlgorithmException;
/**
* Algorithms for performing HMACs. These can be used to create
* MessageDigests.
*/
public class HMACAlgorithm extends DigestAlgorithm {
protected HMACAlgorithm(int oidIndex, String name, OBJECT_IDENTIFIER oid,
int outputSize) {
super(oidIndex, name, oid, outputSize);
if( oid!=null && oidMap.get(oid)==null) {
oidMap.put(oid, this);
}
}
///////////////////////////////////////////////////////////////////////
// OID mapping
///////////////////////////////////////////////////////////////////////
private static Hashtable oidMap = new Hashtable();
/**
* Looks up the HMAC algorithm with the given OID.
*
* @exception NoSuchAlgorithmException If no registered HMAC algorithm
* has the given OID.
*/
public static HMACAlgorithm fromOID(OBJECT_IDENTIFIER oid)
throws NoSuchAlgorithmException
{
Object alg = oidMap.get(oid);
if( alg == null ) {
throw new NoSuchAlgorithmException();
} else {
return (HMACAlgorithm) alg;
}
}
/**
* SHA-X HMAC. This is a Message Authentication Code that uses a
* symmetric key together with SHA-X digesting to create a form of
* signature.
*/
public static final HMACAlgorithm SHA1 = new HMACAlgorithm
(CKM_SHA_1_HMAC, "SHA-1-HMAC",
OBJECT_IDENTIFIER.ALGORITHM.subBranch(26), 20);
public static final HMACAlgorithm SHA256 = new HMACAlgorithm
(SEC_OID_HMAC_SHA256, "SHA-256-HMAC",
OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(9), 32);
public static final HMACAlgorithm SHA384 = new HMACAlgorithm
(SEC_OID_HMAC_SHA384, "SHA-384-HMAC",
OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(10), 48);
public static final HMACAlgorithm SHA512 = new HMACAlgorithm
(SEC_OID_HMAC_SHA512, "SHA-512-HMAC",
OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(11), 64);
}
jss-4.4.3/jss/org/mozilla/jss/crypto/IVParameterSpec.java 0000664 0000000 0000000 00000001312 13261450000 0023316 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.security.spec.AlgorithmParameterSpec;
/**
* An algorithm parameter that consists of an initialization vector (IV).
*/
public class IVParameterSpec implements AlgorithmParameterSpec {
private byte[] iv;
private IVParameterSpec() { }
public IVParameterSpec(byte[] iv) {
this.iv = iv;
}
/**
* Returns a reference to an internal copy of the initialization vector.
*/
public byte[] getIV() {
return iv;
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/IllegalBlockSizeException.java 0000664 0000000 0000000 00000000453 13261450000 0025367 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
public class IllegalBlockSizeException extends Exception { }
jss-4.4.3/jss/org/mozilla/jss/crypto/InternalCertificate.java 0000664 0000000 0000000 00000004724 13261450000 0024255 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* Certificates residing in the internal database. Their trust flags
* can be viewed and modified. Other types of certificates do not
* have trust flags.
*/
public interface InternalCertificate extends X509Certificate
{
////////////////////////////////////////////////////
// Trust manipulation
////////////////////////////////////////////////////
public static final int VALID_PEER = (1<<0);
public static final int TRUSTED_PEER = (1<<1); // CERTDB_TRUSTED
public static final int VALID_CA = (1<<3);
public static final int TRUSTED_CA = (1<<4);
public static final int USER = (1<<6);
public static final int TRUSTED_CLIENT_CA = (1<<7);
/**
* Set the SSL trust flags for this certificate.
*
* @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA,
* TRUSTED_CA, USER, and TRUSTED_CLIENT_CA.
*/
public abstract void setSSLTrust(int trust);
/**
* Set the email (S/MIME) trust flags for this certificate.
*
* @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA,
* TRUSTED_CA, USER, and TRUSTED_CLIENT_CA.
*/
public abstract void setEmailTrust(int trust);
/**
* Set the object signing trust flags for this certificate.
*
* @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA,
* TRUSTED_CA, USER, and TRUSTED_CLIENT_CA.
*/
public abstract void setObjectSigningTrust(int trust);
/**
* Get the SSL trust flags for this certificate.
*
* @return A bitwise OR of the trust flags VALID_PEER, VALID_CA,
* TRUSTED_CA, USER, and TRUSTED_CLIENT_CA.
*/
public abstract int getSSLTrust();
/**
* Get the email (S/MIME) trust flags for this certificate.
*
* @return A bitwise OR of the trust flags VALID_PEER, VALID_CA,
* TRUSTED_CA, USER, and TRUSTED_CLIENT_CA.
*/
public abstract int getEmailTrust();
/**
* Get the object signing trust flags for this certificate.
*
* @return A bitwise OR of the trust flags VALID_PEER, VALID_CA,
* TRUSTED_CA, USER, and TRUSTED_CLIENT_CA.
*/
public abstract int getObjectSigningTrust();
}
jss-4.4.3/jss/org/mozilla/jss/crypto/InvalidDERException.java 0000664 0000000 0000000 00000000731 13261450000 0024130 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* This exception is thrown when we encounter a bogus DER blob.
*/
public class InvalidDERException extends Exception {
public InvalidDERException() { super(); }
public InvalidDERException(String mesg) { super(mesg); }
}
jss-4.4.3/jss/org/mozilla/jss/crypto/InvalidKeyFormatException.java 0000664 0000000 0000000 00000001103 13261450000 0025411 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* An exception of this type is thrown if an encoded private key
* cannot be decoded.
*/
public class InvalidKeyFormatException
extends java.security.spec.InvalidKeySpecException
{
public InvalidKeyFormatException() {
super();
}
public InvalidKeyFormatException(String mesg) {
super(mesg);
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/JSSMessageDigest.java 0000664 0000000 0000000 00000007236 13261450000 0023443 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.security.DigestException;
import java.security.InvalidKeyException;
/**
* A class for performing message digesting (hashing) and MAC operations.
*/
public abstract class JSSMessageDigest {
/**
* Initializes an HMAC digest with the given symmetric key. This also
* has the effect of resetting the digest.
*
* @exception DigestException If this algorithm is not an HMAC algorithm.
* @exception InvalidKeyException If the given key is not valid.
*/
public abstract void initHMAC(SymmetricKey key)
throws DigestException, InvalidKeyException;
/**
* Updates the digest with a single byte of input.
*/
public void update(byte input) throws DigestException {
byte[] in = { input };
update(in, 0, 1);
}
/**
* Updates the digest with a portion of an array.
*
* @param input An array from which to update the digest.
* @param offset The index in the array at which to start digesting.
* @param len The number of bytes to digest.
* @exception DigestException If an error occurs while digesting.
*/
public abstract void update(byte[] input, int offset, int len)
throws DigestException;
/**
* Updates the digest with an array.
*
* @param input An array to feed to the digest.
* @exception DigestException If an error occurs while digesting.
*/
public void update(byte[] input) throws DigestException {
update(input, 0, input.length);
}
/**
* Completes digestion.
*
* @return The, ahem, output of the digest operation.
* @exception DigestException If an error occurs while digesting.
*/
public byte[] digest() throws DigestException {
byte[] output = new byte[getOutputSize()];
digest(output, 0, output.length);
return output;
}
/**
* Completes digesting, storing the result into the provided array.
*
* @param buf The buffer in which to place the digest output.
* @param offset The offset in the buffer at which to store the output.
* @param len The amount of space available in the buffer for the
* digest output.
* @return The number of bytes actually stored into buf.
* @exception DigestException If the provided space is too small for
* the digest, or an error occurs with the digest.
*/
public abstract int digest(byte[] buf, int offset, int len)
throws DigestException;
/**
* Provides final data to the digest, then completes it and returns the
* output.
*
* @param input The digest's last meal.
* @return The completed digest.
* @exception DigestException If an error occurs while digesting.
*/
public byte[] digest(byte[] input) throws DigestException {
update(input);
return digest();
}
/**
* Resets this digest for further use. This clears all input and
* output streams. If this is an HMAC digest, the HMAC key is not
* cleared.
*/
public abstract void reset() throws DigestException;
/**
* Returns the algorithm that this digest uses.
*/
public abstract DigestAlgorithm getAlgorithm();
/**
* Returns the length of the digest created by this digest's
* digest algorithm.
*
* @return The size in bytes of the output of this digest.
*/
public int getOutputSize() {
return getAlgorithm().getOutputSize();
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/JSSSecureRandom.java 0000664 0000000 0000000 00000001247 13261450000 0023302 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* An interface for secure random numbers.
*/
public interface JSSSecureRandom {
/**
* Seed the RNG with the given seed bytes.
*/
public void setSeed(byte[] seed);
/**
* Seed the RNG with the eight bytes contained in seed
.
*/
public void setSeed(long seed);
/**
* Retrieves random bytes and stores them in the given array.
*/
public void nextBytes(byte bytes[]);
}
jss-4.4.3/jss/org/mozilla/jss/crypto/KeyAlreadyImportedException.java 0000664 0000000 0000000 00000001046 13261450000 0025745 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* This exception is thrown if the user tries to import a
* key which is already in the specified token
*/
public class KeyAlreadyImportedException extends java.lang.Exception {
public KeyAlreadyImportedException() {}
public KeyAlreadyImportedException(String mesg) {
super(mesg);
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/KeyGenAlgorithm.java 0000664 0000000 0000000 00000011005 13261450000 0023355 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
import java.util.Hashtable;
import java.security.NoSuchAlgorithmException;
/**
* Algorithms that can be used for generating symmetric keys.
*/
public class KeyGenAlgorithm extends Algorithm {
protected static interface KeyStrengthValidator {
public boolean isValidKeyStrength(int strength);
}
protected static class FixedKeyStrengthValidator
implements KeyStrengthValidator
{
private int strength;
public FixedKeyStrengthValidator(int strength) {
this.strength = strength;
}
public boolean isValidKeyStrength(int strength) {
return this.strength == strength;
}
}
protected KeyGenAlgorithm(int oidTag, String name,
KeyStrengthValidator keyStrengthValidator,
OBJECT_IDENTIFIER oid, Class paramClass)
{
super(oidTag, name, oid, paramClass);
this.keyStrengthValidator = keyStrengthValidator;
if(oid!=null) {
oidMap.put(oid, this);
}
}
///////////////////////////////////////////////////////////////////////
// OIDs
///////////////////////////////////////////////////////////////////////
private static final OBJECT_IDENTIFIER PKCS5 = OBJECT_IDENTIFIER.PKCS5;
private static final OBJECT_IDENTIFIER PKCS12_PBE =
OBJECT_IDENTIFIER.PKCS12.subBranch(1);
///////////////////////////////////////////////////////////////////////
// OID mapping
///////////////////////////////////////////////////////////////////////
private static Hashtable oidMap = new Hashtable();
public static KeyGenAlgorithm fromOID(OBJECT_IDENTIFIER oid)
throws NoSuchAlgorithmException
{
Object alg = oidMap.get(oid);
if( alg == null ) {
throw new NoSuchAlgorithmException(oid.toString());
} else {
return (KeyGenAlgorithm) alg;
}
}
private KeyStrengthValidator keyStrengthValidator;
/**
* Returns true
if the given strength is valid for this
* key generation algorithm. Note that PBE algorithms require
* PBEParameterSpecs rather than strengths. It is the responsibility
* of the caller to verify this.
*/
public boolean isValidStrength(int strength) {
return keyStrengthValidator.isValidKeyStrength(strength);
}
//////////////////////////////////////////////////////////////
public static final KeyGenAlgorithm
DES = new KeyGenAlgorithm(CKM_DES_KEY_GEN, "DES",
new FixedKeyStrengthValidator(56), null, null);
//////////////////////////////////////////////////////////////
public static final KeyGenAlgorithm
DES3 = new KeyGenAlgorithm(CKM_DES3_KEY_GEN, "DESede",
new FixedKeyStrengthValidator(168), null, null);
public static final KeyGenAlgorithm
DESede = DES3;
//////////////////////////////////////////////////////////////
public static final KeyGenAlgorithm
RC4 = new KeyGenAlgorithm(CKM_RC4_KEY_GEN, "RC4",
new KeyStrengthValidator() {
public boolean isValidKeyStrength(int strength) {
return true;
}
}, null, null);
//////////////////////////////////////////////////////////////
public static final KeyGenAlgorithm
PBA_SHA1_HMAC = new KeyGenAlgorithm(
CKM_PBA_SHA1_WITH_SHA1_HMAC,
"PBA/SHA1/HMAC", new FixedKeyStrengthValidator(160),
null, PBEKeyGenParams.class );
//////////////////////////////////////////////////////////////
public static final KeyGenAlgorithm
AES = new KeyGenAlgorithm(CKM_AES_KEY_GEN, "AES",
new KeyStrengthValidator() {
public boolean isValidKeyStrength(int strength) {
return strength==128 || strength==192 || strength==256;
}
}, null, null);
//////////////////////////////////////////////////////////////
public static final KeyGenAlgorithm
RC2 = new KeyGenAlgorithm(CKM_RC2_KEY_GEN, "RC2",
new KeyStrengthValidator() {
public boolean isValidKeyStrength(int strength) {
// 1 byte - 128 bytes
return strength>=8 && strength <= (128*8);
}
}, null, null);
}
jss-4.4.3/jss/org/mozilla/jss/crypto/KeyGenerator.java 0000664 0000000 0000000 00000010363 13261450000 0022731 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.security.spec.AlgorithmParameterSpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.io.CharConversionException;
/**
* Generates symmetric keys for encryption and decryption.
*/
public interface KeyGenerator {
/**
* @param strength Key size in bits. Must be evenly divisible by 8.
*/
public void initialize(int strength)
throws InvalidAlgorithmParameterException;
public void initialize(AlgorithmParameterSpec parameters)
throws InvalidAlgorithmParameterException;
/**
* @param usages The operations the key will be used for after it is
* generated. You have to specify these so that the key can be properly
* marked with the operations it supports. Some PKCS #11 tokens require
* that a key be marked for an operation before it can perform that
* operation. The default is SymmetricKey.Usage.SIGN and
* SymmetricKey.Usage.ENCRYPT.
*/
public void setKeyUsages(SymmetricKey.Usage[] usages);
/**
* Tells the generator to generate temporary or permanent keys.
* Temporary keys are not written permanently to the token. They
* are destroyed by the garbage collector. If this method is not
* called, the default is temporary keys.
*/
public void temporaryKeys(boolean temp);
/**
* Tells the generator to generate sensitive or insensitive keys.
* Certain attributes of a sensitive key cannot be revealed in
* plaintext outside the token. If this method is not called, the
* default is token dependent.
*/
public void sensitiveKeys(boolean sensitive);
/**
* Generates a symmetric key.
*/
public SymmetricKey generate()
throws IllegalStateException, TokenException, CharConversionException;
/**
* Generates an Initialization Vector using a PBE algorithm.
* In order to call this method, the algorithm must be a PBE algorithm,
* and the KeyGenerator must have been initialized with an instance
* of PBEKeyGenParams
.
*
* @return The initialization vector derived from the password and salt
* using the PBE algorithm.
* @exception IllegalStateException If the algorithm is not a PBE
* algorithm, or the KeyGenerator has not been initialized with
* an instance of PBEKeyGenParams
.
* @exception TokenException If an error occurs on the CryptoToken while
* generating the IV.
*/
public byte[] generatePBE_IV()
throws IllegalStateException, TokenException, CharConversionException;
/**
* Allows a SymmetricKey to be cloned on a different token.
*
* @exception SymmetricKey.NotExtractableException If the key material
* cannot be extracted from the current token.
* @exception InvalidKeyException If the owning token cannot process
* the key to be cloned.
*/
public SymmetricKey clone(SymmetricKey key)
throws SymmetricKey.NotExtractableException,
InvalidKeyException, TokenException;
/**
* An interface for converting a password of Java characters into an array
* of bytes. This conversion must be performed to provide a byte array
* to the low-level crypto engine. The default conversion is UTF8.
* Null-termination is not necessary, and indeed is usually incorrect,
* since the password is passed to the crypto engine as a byte array, not
* a C string.
*/
public static interface CharToByteConverter {
/**
* Converts a password of Java characters into a password of
* bytes, using some encoding scheme. The input char array must
* not be modified.
*/
public byte[] convert(char[] chars) throws CharConversionException;
}
/**
* Sets the character to byte converter for passwords. The default
* conversion is UTF8 with no null termination.
*/
public void setCharToByteConverter(CharToByteConverter charToByte);
}
jss-4.4.3/jss/org/mozilla/jss/crypto/KeyPairAlgorithm.java 0000664 0000000 0000000 00000005460 13261450000 0023547 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.security.NoSuchAlgorithmException;
import java.util.Hashtable;
/**
* Algorithms that can be used for keypair generation.
*/
public class KeyPairAlgorithm extends Algorithm {
protected KeyPairAlgorithm(int oidIndex, String name, Algorithm algFamily) {
super(oidIndex, name);
this.algFamily = algFamily;
nameMap.put(name, this);
}
/**
* Returns the algorithm family for a given key pair generation algorithm.
* If a token supports a family and is writable, we can do keypair gen
* on the token even if it doesn't support the keypair gen algorithm.
* We do this by doing the keypair gen on the internal module and then
* moving the key out to the other token.
*/
public Algorithm
getAlgFamily()
{
return algFamily;
}
private static Hashtable nameMap = new Hashtable();
/**
* Looks up a key pair generation algorithm from its name. The names
* are those specified in the JCA spec. For example, "RSA" and "DSA".
*
* @throws NoSuchAlgorithmException If the name of the algorithm is not
* recognized as a supported algorithm.
*/
public static KeyPairAlgorithm fromString(String algName)
throws NoSuchAlgorithmException
{
KeyPairAlgorithm alg = (KeyPairAlgorithm)nameMap.get(algName);
if( alg == null ) {
throw new NoSuchAlgorithmException();
}
return alg;
}
protected Algorithm algFamily;
////////////////////////////////////////////////////////////////
// Key-Pair Generation Algorithms
////////////////////////////////////////////////////////////////
public static final Algorithm
RSAFamily = new Algorithm(SEC_OID_PKCS1_RSA_ENCRYPTION, "RSA");
public static final Algorithm
DSAFamily = new Algorithm(SEC_OID_ANSIX9_DSA_SIGNATURE, "DSA");
public static final Algorithm
// To support both ECDSA and ECDH, it is best to provide two EC Families;
// However, since there is no token that does only CKM_DERIVE to
// date, we will just do ECDSA for now as it is sufficient enough today.
// This fix will support tokens that do not do ECDH
ECFamily = new Algorithm(SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST, "EC");
public static final KeyPairAlgorithm
RSA = new KeyPairAlgorithm(CKM_RSA_PKCS_KEY_PAIR_GEN, "RSA", RSAFamily);
public static final KeyPairAlgorithm
DSA = new KeyPairAlgorithm(CKM_DSA_KEY_PAIR_GEN, "DSA", DSAFamily);
public static final KeyPairAlgorithm
EC = new KeyPairAlgorithm(CKM_EC_KEY_PAIR_GEN, "EC", ECFamily);
}
jss-4.4.3/jss/org/mozilla/jss/crypto/KeyPairGenerator.java 0000664 0000000 0000000 00000014647 13261450000 0023556 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.security.*;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
/**
* Generates RSA and DSA key pairs. Each CryptoToken provides a
* KeyPairGenerator, which can be used to generate key pairs on that token.
* A given token may not support all algorithms, and some tokens may not
* support any key pair generation. If a token does not support key pair
* generation, the Netscape internal token may do it instead. Call
* keygenOnInternalToken
to find out if this is happening.
*
* @see org.mozilla.jss.crypto.CryptoToken#getKeyPairGenerator
*/
public class KeyPairGenerator {
/**
* Creates a new key pair generator. KeyPairGenerators should
* be obtained by calling CryptoToken.getKeyPairGenerator
* instead of calling this constructor.
*
* @param algorithm The type of keys that the generator will be
* used to generate.
* @param engine The engine object that provides the implementation for
* the class.
*/
public KeyPairGenerator(KeyPairAlgorithm algorithm,
KeyPairGeneratorSpi engine) {
this.algorithm = algorithm;
this.engine = engine;
}
/**
* Generates a new key pair.
*
* @return A new key pair. The keys reside on the CryptoToken that
* provided this KeyPairGenerator
.
* @exception TokenException If an error occurs on the CryptoToken
* in the process of generating the key pair.
*/
public java.security.KeyPair
genKeyPair() throws TokenException {
return engine.generateKeyPair();
}
/**
* @return The type of key that this generator generates.
*/
public KeyPairAlgorithm getAlgorithm() {
return algorithm;
}
/**
* Initializes the generator with algorithm-specific parameters.
* The SecureRandom parameters is ignored.
*
* @param params Algorithm-specific parameters for the key pair generation.
* @param random This parameter is ignored. NSS does not accept
* an external source of random numbers.
* @exception InvalidAlgorithmParameterException If the parameters are
* inappropriate for the type of key pair that is being generated,
* or they are not supported by this generator.
* @see org.mozilla.jss.crypto.RSAParameterSpec
* @see java.security.spec.DSAParameterSpec
*/
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException
{
engine.initialize(params, random);
}
/**
* Initializes the generator with algorithm-specific parameters.
*
* @param params Algorithm-specific parameters for the key pair generation.
* @exception InvalidAlgorithmParameterException If the parameters are
* inappropriate for the type of key pair that is being generated,
* or they are not supported by this generator.
* @see org.mozilla.jss.crypto.RSAParameterSpec
* @see java.security.spec.DSAParameterSpec
*/
public void initialize(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException
{
engine.initialize(params, null);
}
/**
* Initializes the generator with the strength of the keys.
* The SecureRandom parameter is ignored.
*
* @param strength The strength of the keys that will be generated.
* Usually this is the length of the key in bits.
* @param random This parameter is ignored. NSS does not accept
* an external source of random numbers.
*/
public void initialize(int strength, SecureRandom random) {
engine.initialize(strength, random);
}
/**
* Initializes the generator with the strength of the keys.
*
* @param strength The strength of the keys that will be generated.
* Usually this is the length of the key in bits.
*/
public void initialize(int strength) {
engine.initialize(strength, null);
}
/**
* @return true if the keypair generation will take place on the
* internal token rather than the current token. This will
* happen if the token does not support keypair generation
* but does support this algorithm and is writable. In this
* case the keypair will be generated on the Netscape internal
* token and then moved to this token.
*/
public boolean keygenOnInternalToken() {
return engine.keygenOnInternalToken();
}
/**
* Tells the generator to generate temporary or permanent keypairs.
* Temporary keys are not written permanently to the token. They
* are destroyed by the garbage collector. If this method is not
* called, the default is permanent keypairs.
* @param temp
*/
public void temporaryPairs(boolean temp) {
engine.temporaryPairs(temp);
}
/**
* Tells the generator to generate sensitive or insensitive keypairs.
* Certain attributes of a sensitive key cannot be revealed in
* plaintext outside the token. If this method is not called, the
* default depends on the temporaryPairs mode for backward
* compatibility. The default is sensitive keypairs if the
* temporaryPairs mode is false, or insensitive keypairs if the
* temporaryPairs mode is true.
* @param sensitive
*/
public void sensitivePairs(boolean sensitive) {
engine.sensitivePairs(sensitive);
}
/**
* Tells the generator to generate extractable or unextractable
* keypairs. Extractable keys can be extracted from the token after
* wrapping. If this method is not called, the default is token
* dependent.
* @param extractable
*/
public void extractablePairs(boolean extractable) {
engine.extractablePairs(extractable);
}
public void setKeyPairUsages(KeyPairGeneratorSpi.Usage[] usages,
KeyPairGeneratorSpi.Usage[] usages_mask) {
engine.setKeyPairUsages(usages,usages_mask);
}
public int getCurveCodeByName(String curveName)
throws InvalidParameterException {
return engine.getCurveCodeByName(curveName);
}
protected KeyPairAlgorithm algorithm;
protected KeyPairGeneratorSpi engine;
}
jss-4.4.3/jss/org/mozilla/jss/crypto/KeyPairGeneratorSpi.java 0000664 0000000 0000000 00000005302 13261450000 0024216 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.security.*;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
public abstract class KeyPairGeneratorSpi {
public KeyPairGeneratorSpi() {
}
public abstract void initialize(int strength, SecureRandom random);
public abstract void initialize(AlgorithmParameterSpec params,
SecureRandom random)
throws InvalidAlgorithmParameterException;
public abstract KeyPair generateKeyPair() throws TokenException;
public abstract int getCurveCodeByName(String curveName) throws InvalidParameterException;
public abstract void temporaryPairs(boolean temp);
public abstract void sensitivePairs(boolean sensitive);
public abstract void extractablePairs(boolean extractable);
public abstract boolean keygenOnInternalToken();
/**
* In PKCS #11, each keypair can be marked with the operations it will
* be used to perform. Some tokens require that a key be marked for
* an operation before the key can be used to perform that operation;
* other tokens don't care. NSS provides a way to specify a set of
* flags and a corresponding mask for these flags. If a specific usage
* is desired set the value for that usage. If it is not set, let NSS
* behave in it's default fashion. If a behavior is desired, also set
* that behavior in the mask as well as the flags.
*
*/
public final static class Usage {
private Usage() { }
private Usage(int val) { this.val = val;}
private int val;
public int getVal() { return val; }
// these enums must match the
// opFlagForUsage listed in PK11KeyPairGenerator.java
public static final Usage ENCRYPT = new Usage(0);
public static final Usage DECRYPT = new Usage(1);
public static final Usage SIGN = new Usage(2);
public static final Usage SIGN_RECOVER = new Usage(3);
public static final Usage VERIFY = new Usage(4);
public static final Usage VERIFY_RECOVER = new Usage(5);
public static final Usage WRAP = new Usage(6);
public static final Usage UNWRAP = new Usage(7);
public static final Usage DERIVE = new Usage(8);
}
/**
* setKeyPairUsages
* @param usages
* @param usages_mask
*/
public abstract void setKeyPairUsages(KeyPairGeneratorSpi.Usage[] usages,
KeyPairGeneratorSpi.Usage[] usages_mask);
}
jss-4.4.3/jss/org/mozilla/jss/crypto/KeyWrapAlgorithm.java 0000664 0000000 0000000 00000010071 13261450000 0023557 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.util.Hashtable;
import java.security.NoSuchAlgorithmException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.RC2ParameterSpec;
/**
*
*/
public class KeyWrapAlgorithm extends Algorithm {
protected KeyWrapAlgorithm(int oidTag, String name, Class paramClass,
boolean padded, int blockSize) {
super(oidTag, name, null, paramClass);
this.padded = padded;
this.blockSize = blockSize;
if( name != null ) {
nameMap.put(name.toLowerCase(), this);
}
}
protected KeyWrapAlgorithm(int oidTag, String name, Class []paramClasses,
boolean padded, int blockSize) {
super(oidTag, name, null, paramClasses);
this.padded = padded;
this.blockSize = blockSize;
if( name != null ) {
nameMap.put(name.toLowerCase(), this);
}
}
private boolean padded;
private int blockSize;
private static Hashtable nameMap = new Hashtable();
public static KeyWrapAlgorithm fromString(String name)
throws NoSuchAlgorithmException
{
Object alg = nameMap.get( name.toLowerCase() );
if( alg == null ) {
throw new NoSuchAlgorithmException();
} else {
return (KeyWrapAlgorithm) alg;
}
}
public boolean isPadded() {
return padded;
}
public int getBlockSize() {
return blockSize;
}
private static Class[] IVParameterSpecClasses = null;
static {
IVParameterSpecClasses = new Class[2];
IVParameterSpecClasses[0] = IVParameterSpec.class;
IVParameterSpecClasses[1] = IvParameterSpec.class;
}
public static final KeyWrapAlgorithm
DES_ECB = new KeyWrapAlgorithm(SEC_OID_DES_ECB, "DES/ECB", (Class) null,
false, 8);
public static final KeyWrapAlgorithm
DES_CBC = new KeyWrapAlgorithm(SEC_OID_DES_CBC, "DES/CBC",
IVParameterSpecClasses, false, 8);
public static final KeyWrapAlgorithm
DES_CBC_PAD = new KeyWrapAlgorithm(CKM_DES_CBC_PAD, "DES/CBC/Pad",
IVParameterSpecClasses, true, 8);
public static final KeyWrapAlgorithm
DES3_ECB = new KeyWrapAlgorithm(CKM_DES3_ECB, "DES3/ECB", (Class)null,
false, 8);
public static final KeyWrapAlgorithm
DES3_CBC = new KeyWrapAlgorithm(SEC_OID_DES_EDE3_CBC, "DES3/CBC",
IVParameterSpecClasses, false, 8);
public static final KeyWrapAlgorithm
DES3_CBC_PAD = new KeyWrapAlgorithm(CKM_DES3_CBC_PAD, "DES3/CBC/Pad",
IVParameterSpecClasses, true, 8);
public static final KeyWrapAlgorithm
RSA = new KeyWrapAlgorithm(SEC_OID_PKCS1_RSA_ENCRYPTION, "RSA",
(Class) null, false, 0);
public static final KeyWrapAlgorithm
PLAINTEXT = new KeyWrapAlgorithm(0, "Plaintext", (Class) null,
false, 0);
public static final KeyWrapAlgorithm
AES_ECB = new KeyWrapAlgorithm(CKM_AES_ECB, "AES/ECB/NoPadding",
(Class) null, false, 16);
public static final KeyWrapAlgorithm
AES_CBC = new KeyWrapAlgorithm(CKM_AES_CBC, "AES/CBC/NoPadding",
IVParameterSpecClasses, false, 16);
public static final KeyWrapAlgorithm
AES_CBC_PAD = new KeyWrapAlgorithm(CKM_AES_CBC_PAD, "AES/CBC/PKCS5Padding",
IVParameterSpecClasses, true, 16);
public static final KeyWrapAlgorithm
RC2_CBC_PAD = new KeyWrapAlgorithm(CKM_RC2_CBC_PAD, "RC2/CBC/PKCS5Padding",
RC2ParameterSpec.class, true, 8);
public static final KeyWrapAlgorithm
AES_KEY_WRAP = new KeyWrapAlgorithm(CKM_NSS_AES_KEY_WRAP, "AES KeyWrap",
(Class) null, true, 8);
public static final KeyWrapAlgorithm
AES_KEY_WRAP_PAD = new KeyWrapAlgorithm(CKM_NSS_AES_KEY_WRAP_PAD, "AES KeyWrap/Padding",
(Class) null, true, 8);
}
jss-4.4.3/jss/org/mozilla/jss/crypto/KeyWrapper.java 0000664 0000000 0000000 00000012157 13261450000 0022426 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.security.spec.AlgorithmParameterSpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.PublicKey;
import java.security.InvalidKeyException;
public interface KeyWrapper {
public void initWrap(SymmetricKey wrappingKey,
AlgorithmParameterSpec parameters)
throws InvalidKeyException, InvalidAlgorithmParameterException;
public void initWrap(PublicKey wrappingKey,
AlgorithmParameterSpec parameters)
throws InvalidKeyException, InvalidAlgorithmParameterException;
/**
* For wrapping keys in plaintext.
*/
public void initWrap()
throws InvalidKeyException, InvalidAlgorithmParameterException;
public void initUnwrap(SymmetricKey unwrappingKey,
AlgorithmParameterSpec parameters)
throws InvalidKeyException, InvalidAlgorithmParameterException;
public void initUnwrap(PrivateKey unwrappingKey,
AlgorithmParameterSpec parameters)
throws InvalidKeyException, InvalidAlgorithmParameterException;
/**
* For plaintext-wrapped keys.
*/
public void initUnwrap()
throws InvalidKeyException, InvalidAlgorithmParameterException;
public byte[] wrap(PrivateKey toBeWrapped)
throws InvalidKeyException, IllegalStateException, TokenException;
public byte[] wrap(SymmetricKey toBeWrapped)
throws InvalidKeyException, IllegalStateException, TokenException;
/**
* Unwraps a private key, creating a permanent private key object.
* A permanent private key object resides on a token until it is
* explicitly deleted from the token.
*
* @param publicKey Used to calculate the key identifier that must be stored
* with the private key. Must be a RSAPublicKey
or a
* DSAPublicKey
.
* @exception InvalidKeyException If the type of the public key does not
* match the type of the private key to be unwrapped.
*/
public PrivateKey unwrapPrivate(byte[] wrapped, PrivateKey.Type type,
PublicKey publicKey)
throws TokenException, InvalidKeyException, IllegalStateException;
/**
* Unwraps a private key, creating a temporary private key object.
* A temporary
* private key is one that does not permanently reside on a token.
* As soon as it is garbage-collected, it is gone forever.
*
* @param publicKey Used to calculate the key identifier that must be stored
* with the private key. Must be a RSAPublicKey
or a
* DSAPublicKey
.
* @exception InvalidKeyException If the type of the public key does not
* match the type of the private key to be unwrapped.
*/
public PrivateKey unwrapTemporaryPrivate(byte[] wrapped,
PrivateKey.Type type, PublicKey publicKey)
throws TokenException, InvalidKeyException, IllegalStateException;
/**
* @param keyLength The expected length of the key in bytes. This is
* only used for variable-length keys (RC4) and non-padding
* algorithms. Otherwise, it can be set to anything(like 0).
* @param usage The operation the key will be used for after it is
* unwrapped. You have to specify this so that the key can be properly
* marked with the operation it supports. Some PKCS #11 tokens require
* that a key be marked for an operation before it can perform that
* operation.
*/
public SymmetricKey unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type,
SymmetricKey.Usage usage, int keyLength)
throws TokenException, IllegalStateException,
InvalidAlgorithmParameterException;
/**
* Unwraps a key and allows it to be used for all operations.
* @param keyLength The expected length of the key in bytes. This is
* only used for variable-length keys (RC4) and non-padding
* algorithms. Otherwise, it can be set to anything(like 0).
*/
public SymmetricKey unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type,
int keyLength)
throws TokenException, IllegalStateException,
InvalidAlgorithmParameterException;
public SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type,
SymmetricKey.Usage usage, int keyLength)
throws TokenException, IllegalStateException,
InvalidAlgorithmParameterException;
/**
* Unwraps a key and allows it to be used for all operations.
* @param keyLength The expected length of the key in bytes. This is
* only used for variable-length keys (RC4) and non-padding
* algorithms. Otherwise, it can be set to anything(like 0).
*/
public SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type,
int keyLength)
throws TokenException, IllegalStateException,
InvalidAlgorithmParameterException;
}
jss-4.4.3/jss/org/mozilla/jss/crypto/Makefile 0000664 0000000 0000000 00000003545 13261450000 0021133 0 ustar 00root root 0000000 0000000 #! gmake
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#######################################################################
# (1) Include initial platform-independent assignments (MANDATORY). #
#######################################################################
include manifest.mn
#######################################################################
# (2) Include "global" configuration information. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
# (3) Include "component" configuration information. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/config/config.mk
#######################################################################
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
#######################################################################
include config.mk
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/rules.mk
#######################################################################
# (6) Execute "component" rules. (OPTIONAL) #
#######################################################################
#######################################################################
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################
jss-4.4.3/jss/org/mozilla/jss/crypto/NoSuchItemOnTokenException.java 0000664 0000000 0000000 00000001041 13261450000 0025516 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* Thrown if a cryptographic item does not exist on the token it is
* trying to be used on.
*/
public class NoSuchItemOnTokenException extends Exception {
public
NoSuchItemOnTokenException() {}
public
NoSuchItemOnTokenException( String message ) {
super( message );
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/NoSuchPaddingException.java 0000664 0000000 0000000 00000000615 13261450000 0024676 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* This class is a stub for javax.crypto.NoSuchPaddingException until we
* move to JDK 1.2.
*/
public class NoSuchPaddingException extends Exception { }
jss-4.4.3/jss/org/mozilla/jss/crypto/ObjectNotFoundException.java 0000664 0000000 0000000 00000000747 13261450000 0025101 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* This exception is thrown whenever something isn't implemented.
*/
public class ObjectNotFoundException extends Exception {
public ObjectNotFoundException() { super(); }
public ObjectNotFoundException(String mesg) { super(mesg); }
}
jss-4.4.3/jss/org/mozilla/jss/crypto/PBEAlgorithm.java 0000664 0000000 0000000 00000012621 13261450000 0022606 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
import java.util.Hashtable;
import java.security.NoSuchAlgorithmException;
/**
* Algorithms that can be used for generating symmetric keys from passwords.
*/
public class PBEAlgorithm extends KeyGenAlgorithm {
private EncryptionAlgorithm encAlg;
private int saltLength;
protected PBEAlgorithm(int oidTag, String name, int validStrength,
OBJECT_IDENTIFIER oid, EncryptionAlgorithm encAlg, int saltLength)
{
super(oidTag, name, new FixedKeyStrengthValidator(validStrength),
oid, PBEKeyGenParams.class);
this.encAlg = encAlg;
this.saltLength = saltLength;
}
/**
* Returns the EncryptionAlgorithm that should be used with keys
* generated with this PBEAlgorithm. For example,
* PBE_MD2_DES_CBC.getEncryptionAlg()
returns
* EncryptionAlgorithm.DES_CBC
.
*/
public EncryptionAlgorithm getEncryptionAlg() {
return encAlg;
}
/**
* Returns the number of bytes of salt that should be supplied when
* generating keys with this algorithm.
*
* generate
methods.
* They will return a new set of PQG parameters. To verify existing PQG
* parameters, create a new PQGParams
object with the
* constructor and call paramsAreValid
on the object.
*
* CryptoManager.initialize
before
* using this class.
*
*/
public class PQGParams extends DSAParameterSpec {
/**
* Creates a PQGParams object from a set of pre-computed DSA
* parameters.
*
* @param P The DSA prime parameter.
* @param Q The DSA sub-prime parameter.
* @param G The DSA base parameter.
* @param seed The Seed used to calculate P, Q, and G.
* @param counter The Counter (C) used to calculate P, Q, and G.
* @param H The H value used to generate P, Q, and G.
*/
public PQGParams(BigInteger P, BigInteger Q, BigInteger G,
BigInteger seed, int counter, BigInteger H)
{
super(P, Q, G);
this.seed = seed;
this.counter = counter;
this.H = H;
}
/**
* Generates P, Q, and G parameters for DSA key generation. Also
* provides the seed, counter, and H values for verification of the
* P, Q, and G. The parameters are generated and then verified
* before being returned. The length of the Seed will equal the
* length of P.
*
* It is necessary to call one of the
* CryptoManager.initialize
functions before calling
* this method.
*
* @param keySize The size of P in bits. Keys generated by these P,
* Q, and G values will have this length. Valid key sizes
* are multiples of 64 in the closed interval [512,1024].
* This also dictates the length of H and Seed.
* @return A new set of P, Q, and G parameters, along with the Seed,
* Counter, and H values used to generate them.
* @exception java.security.InvalidParameterException If the keySize
* is outside the bounds described by the DSA key pair
* generation algorithm.
* @exception org.mozilla.jss.crypto.PQGParamGenException If an error
* occurs during the generation process.
* @see org.mozilla.jss.CryptoManager#initialize
*/
public static PQGParams
generate(int keySize)
throws java.security.InvalidParameterException,
PQGParamGenException
{
PQGParams pqg = generateNative(keySize);
if( ! pqg.paramsAreValid() ) {
throw new PQGParamGenException(
"Generated parameters did not verify correctly");
}
return pqg;
}
/**
* Does the actual work of generation, but does not verify.
*/
private static native PQGParams
generateNative(int keySize)
throws java.security.InvalidParameterException,
PQGParamGenException;
/**
* Generates P, Q, and G parameters for DSA key generation. Also
* provides the seed, counter, and H values for verification of the
* P, Q, and G. The parameters are generated and then verified
* before being returned.
*
* It is necessary to call one of the
* CryptoManager.initialize
functions before calling
* this method.
*
* @param keySize The size of P in bits. Keys generated by these P,
* Q, and G values will have this length. Valid key sizes
* are multiples of 64 in the closed interval [512,1024].
* This also dictates the length of H.
* @param seedBytes The number of bytes in the Seed value used to
* generate P, Q, and G. seedBytes
must be
* from the closed interval [20,255].
* @return A new set of P, Q, and G parameters, along with the Seed,
* Counter, and H values used to generate them.
* @exception java.security.InvalidParameterException If the keySize
* or number of seed bytes is outside the bounds described by the
* DSA key pair generation algorithm.
* @exception org.mozilla.jss.crypto.PQGParamGenException If an error
* occurs during the generation process.
* @see org.mozilla.jss.CryptoManager#initialize
*/
public static PQGParams
generate(int keySize, int seedBytes)
throws java.security.InvalidParameterException,
PQGParamGenException
{
PQGParams pqg = generateNative(keySize, seedBytes);
if( ! pqg.paramsAreValid() ) {
throw new PQGParamGenException(
"Generated parameters did not verify correctly");
}
return pqg;
}
/**
* Does the actual work of generation, but does not verify.
*/
private static native PQGParams
generateNative(int keySize, int seedBytes)
throws java.security.InvalidParameterException,
PQGParamGenException;
/**
* Produces an unsigned byte-array representation of a BigInteger.
*
*
* SEQUENCE {
* keyid OCTET STRING,
* alg AlgorithmIdentifier,
* ciphertext OCTET STRING }
*
*
* CryptoToken
s.
*
* @see org.mozilla.jss.crypto.CryptoToken#getSignatureContext
*/
public class Signature {
protected Signature() { }
Signature(SignatureAlgorithm algorithm, SignatureSpi engine) {
this.algorithm = algorithm;
this.engine = engine;
}
/**
* This is not supported yet.
*/
public Provider getProvider() {
Assert.notYetImplemented("Signature.getProvider");
return null;
}
/**
* Supplying sources of randoms is not supported yet.
public void initSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException, TokenException
{
engine.engineInitSign(privateKey, random);
}
*/
/**
* Initialize the signature context for signing.
* @param privateKey The private key with which to sign.
* @exception InvalidKeyException If the key is the wrong type for the
* algorithm or does not exist on the token of this signature
* context.
* @exception TokenException If an error occurred on the token.
*/
public void initSign(PrivateKey privateKey)
throws InvalidKeyException, TokenException
{
engine.engineInitSign(privateKey);
}
/**
* Initialize the signature context for verifying.
* @param publicKey The public key with which to verify the signature.
* @exception InvalidKeyException If the key is the wrong type for the
* algorithm.
* @exception TokenException If an error occurs on the token.
*/
public void initVerify(PublicKey publicKey)
throws InvalidKeyException, TokenException
{
engine.engineInitVerify(publicKey);
}
/**
* Set parameters for the signing algorithm. This is currently not
* supported or needed.
* @param params Parameters for the signing algorithm.
* @exception InvalidAlgorithmParameterException If there is something wrong
* with the parameters.
* @exception TokenException If an error occurs on the token.
*/
public void setParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException, TokenException
{
engine.engineSetParameter(params);
}
/**
* Finish a signing operation and return the signature.
* @exception SignatureException If an error occurs with the signing
* operation.
* @exception TokenException If an error occurs on the token.
* @return The signature.
*/
public byte[] sign() throws SignatureException, TokenException
{
return engine.engineSign();
}
/**
* Finish a signing operation and store the signature in the provided
* buffer.
* @param outbuf Buffer to hold the signature
* @param offset Offset in buffer at which to store signature.
* @param len Number of bytes of buffer available for signature.
* @return int The number of bytes placed into outbuf.
* @exception SignatureException If an error occurred while signing, or
* len was insufficient to contain the signature.
* @exception TokenException If an error occurred on the token.
*/
public int sign(byte[] outbuf, int offset, int len)
throws SignatureException, TokenException
{
return engine.engineSign(outbuf, offset, len);
}
/**
* Finish a verification operation.
* @param signature The signature to be verified.
* @return true if the signature is valid, false if it is invalid.
* @exception SignatureException If an error occurred with the verification
* operation
* @exception TokenException If an error occurred on the token.
*/
public boolean verify(byte[] signature)
throws SignatureException, TokenException
{
return engine.engineVerify(signature);
}
/**
* Provide more data for a signature or verification operation.
* @param b A byte to be signed or verified.
* @exception SignatureException If an error occurs in the
* signature/verifcation.
* @exception TokenException If an error occurs on the token.
*/
public void update(byte b)
throws SignatureException, TokenException
{
engine.engineUpdate(b);
}
/**
* Provide more data for a signature or verification operation.
* @param data An array of bytes to be signed or verified.
* @exception SignatureException If an error occurs in the
* signature/verifcation.
* @exception TokenException If an error occurs on the token.
*/
public void update(byte[] data)
throws SignatureException, TokenException
{
engine.engineUpdate(data, 0, data.length);
}
/**
* Provide more data for a signature or verification operation.
* @param data An array of bytes, some of which will be signed or verified.
* @param off The beginning offset of the bytes to be signed/verified.
* @param len The number of bytes to be signed/verified.
* @exception SignatureException If an error occurs in the
* signature/verification.
* @exception TokenException If an error occurs on the token.
*/
public void update(byte[] data, int off, int len)
throws SignatureException, TokenException
{
engine.engineUpdate(data, off, len);
}
/**
* Returns the name of the algorithm to be used for signing.
*/
public String getAlgorithm() {
return algorithm.toString();
}
/**
* Returns the algorithm to be used for signing.
*/
public SignatureAlgorithm getAlgorithmID() {
return algorithm;
}
/**
* Cloning is not supported yet
*/
protected Object clone() throws CloneNotSupportedException {
// no cloning for now
throw new CloneNotSupportedException();
}
protected SignatureAlgorithm algorithm;
protected SignatureSpi engine;
}
jss-4.4.3/jss/org/mozilla/jss/crypto/SignatureAlgorithm.java 0000664 0000000 0000000 00000016450 13261450000 0024145 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
import java.util.Hashtable;
import java.security.NoSuchAlgorithmException;
/**
* Algorithms that can be used for signing.
*/
public class SignatureAlgorithm extends Algorithm {
private static Hashtable oidMap = new Hashtable();
protected SignatureAlgorithm(int oidIndex, String name,
SignatureAlgorithm signingAlg, DigestAlgorithm digestAlg,
OBJECT_IDENTIFIER oid)
{
super(oidIndex, name, oid);
if(signingAlg == null) {
this.signingAlg = this;
} else {
this.signingAlg = signingAlg;
}
this.digestAlg = digestAlg;
oidMap.put(oid, this);
}
/**
* Looks up the signature algorithm with the given OID.
* @exception NoSuchAlgorithmException If no algorithm is found with this
* OID.
*/
public static SignatureAlgorithm fromOID(OBJECT_IDENTIFIER oid)
throws NoSuchAlgorithmException
{
Object alg = oidMap.get(oid);
if( alg == null ) {
throw new NoSuchAlgorithmException();
}
return (SignatureAlgorithm) alg;
}
/**
* The raw encryption portion of the signature algorithm. For example,
* SignatureAlgorithm.RSASignatureWithMD2Digest.getSigningAlg ==
* SignatureAlgorithm.RSASignature.
*/
public Algorithm getSigningAlg() {
return signingAlg;
}
public SignatureAlgorithm getRawAlg() {
return signingAlg;
}
private SignatureAlgorithm signingAlg;
/**
* The digest portion of the signature algorithm.
*/
public DigestAlgorithm getDigestAlg() throws NoSuchAlgorithmException {
if( digestAlg == null ) {
throw new NoSuchAlgorithmException();
}
return digestAlg;
}
private DigestAlgorithm digestAlg;
//////////////////////////////////////////////////////////////////////
// Signature Algorithms
//////////////////////////////////////////////////////////////////////
/**********************************************************************
* Raw RSA signing. This algorithm does not do any hashing, it merely
* encrypts its input, which should be a hash.
*/
public static final SignatureAlgorithm
RSASignature = new SignatureAlgorithm(SEC_OID_PKCS1_RSA_ENCRYPTION, "RSA",
null, null, OBJECT_IDENTIFIER.PKCS1.subBranch(1) );
/**********************************************************************
* Raw DSA signing. This algorithm does not do any hashing, it merely
* operates on its input, which should be a hash.
*/
public static final SignatureAlgorithm
DSASignature = new SignatureAlgorithm(SEC_OID_ANSIX9_DSA_SIGNATURE, "DSA",
null, null, ANSI_X9_ALGORITHM.subBranch(1) );
/**********************************************************************
* Raw EC signing. This algorithm does not do any hashing, it merely
* operates on its input, which should be a hash.
*/
public static final SignatureAlgorithm
ECSignature = new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST,
"EC",
null, null, ANSI_X962_OID.subBranch(2).subBranch(1) );
//////////////////////////////////////////////////////////////////////
public static final SignatureAlgorithm
RSASignatureWithMD2Digest =
new SignatureAlgorithm(SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION,
"RSASignatureWithMD2Digest", RSASignature, DigestAlgorithm.MD2,
OBJECT_IDENTIFIER.PKCS1.subBranch(2) );
//////////////////////////////////////////////////////////////////////
public static final SignatureAlgorithm
RSASignatureWithMD5Digest =
new SignatureAlgorithm(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,
"RSASignatureWithMD5Digest", RSASignature, DigestAlgorithm.MD5,
OBJECT_IDENTIFIER.PKCS1.subBranch(4) );
//////////////////////////////////////////////////////////////////////
public static final SignatureAlgorithm
RSASignatureWithSHA1Digest =
new SignatureAlgorithm(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION,
"RSASignatureWithSHA1Digest", RSASignature, DigestAlgorithm.SHA1,
OBJECT_IDENTIFIER.PKCS1.subBranch(5) );
//////////////////////////////////////////////////////////////////////
public static final SignatureAlgorithm
DSASignatureWithSHA1Digest =
new SignatureAlgorithm(SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST,
"DSASignatureWithSHA1Digest", DSASignature, DigestAlgorithm.SHA1,
ANSI_X9_ALGORITHM.subBranch(3) );
//////////////////////////////////////////////////////////////////////
public static final SignatureAlgorithm
ECSignatureWithSHA1Digest =
new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE,
"ECSignatureWithSHA1Digest", ECSignature, DigestAlgorithm.SHA1,
ANSI_X962_OID.subBranch(4).subBranch(1) );
//////////////////////////////////////////////////////////////////////
public static final SignatureAlgorithm
ECSignatureWithSHA256Digest =
new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE,
"ECSignatureWithSHA256Digest", ECSignature, DigestAlgorithm.SHA256,
ANSI_X962_OID.subBranch(4).subBranch(3).subBranch(2) );
//////////////////////////////////////////////////////////////////////
public static final SignatureAlgorithm
ECSignatureWithSHA384Digest =
new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE,
"ECSignatureWithSHA384Digest", ECSignature, DigestAlgorithm.SHA384,
ANSI_X962_OID.subBranch(4).subBranch(3).subBranch(3) );
//////////////////////////////////////////////////////////////////////
public static final SignatureAlgorithm
ECSignatureWithSHA512Digest =
new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE,
"ECSignatureWithSHA512Digest", ECSignature, DigestAlgorithm.SHA512,
ANSI_X962_OID.subBranch(4).subBranch(3).subBranch(4) );
//////////////////////////////////////////////////////////////////////
public static final SignatureAlgorithm
RSASignatureWithSHA256Digest =
new SignatureAlgorithm(SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION,
"RSASignatureWithSHA256Digest", RSASignature, DigestAlgorithm.SHA256,
OBJECT_IDENTIFIER.PKCS1.subBranch(11));
//////////////////////////////////////////////////////////////////////
public static final SignatureAlgorithm
RSASignatureWithSHA384Digest =
new SignatureAlgorithm(SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION,
"RSASignatureWithSHA384Digest", RSASignature, DigestAlgorithm.SHA384,
OBJECT_IDENTIFIER.PKCS1.subBranch(12));
//////////////////////////////////////////////////////////////////////
public static final SignatureAlgorithm
RSASignatureWithSHA512Digest =
new SignatureAlgorithm(SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION,
"RSASignatureWithSHA512Digest", RSASignature, DigestAlgorithm.SHA512,
OBJECT_IDENTIFIER.PKCS1.subBranch(13));
}
jss-4.4.3/jss/org/mozilla/jss/crypto/SignatureSpi.java 0000664 0000000 0000000 00000002650 13261450000 0022747 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.security.*;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
/**
* You don't need to use this unless you are hacking JSS.
*/
public abstract class SignatureSpi {
public abstract void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException, TokenException;
public abstract void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException, TokenException;
public abstract void engineInitSign(PrivateKey privateKey,
SecureRandom random)
throws InvalidKeyException, TokenException;
public abstract void engineUpdate(byte b)
throws SignatureException, TokenException;
public abstract void engineUpdate(byte[] b, int off, int len)
throws SignatureException, TokenException;
public abstract byte[] engineSign()
throws SignatureException, TokenException;
public abstract int engineSign(byte[] outbuf, int offset, int len)
throws SignatureException, TokenException;
public abstract boolean engineVerify(byte[] sigBytes)
throws SignatureException, TokenException;
public abstract void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException, TokenException;
}
jss-4.4.3/jss/org/mozilla/jss/crypto/SymmetricKey.java 0000664 0000000 0000000 00000007553 13261450000 0022766 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.util.Hashtable;
import java.security.NoSuchAlgorithmException;
public interface SymmetricKey {
public static final Type DES = Type.DES;
public static final Type DES3 = Type.DES3;
public static final Type RC4 = Type.RC4;
public static final Type RC2 = Type.RC2;
public static final Type SHA1_HMAC = Type.SHA1_HMAC;
public static final Type AES = Type.AES;
public Type getType();
public CryptoToken getOwningToken();
public int getStrength();
public int getLength();
public byte[] getKeyData() throws NotExtractableException;
public static class NotExtractableException extends Exception {
public NotExtractableException() {
super();
}
public NotExtractableException(String mesg) {
super(mesg);
}
}
String getAlgorithm();
byte[] getEncoded();
String getFormat();
String getNickName();
void setNickName(String nickName);
public final static class Type {
// all names converted to lowercase for case insensitivity
private static Hashtable nameMap = new Hashtable();
private String name;
private KeyGenAlgorithm keyGenAlg;
private Type() { }
private Type(String name, KeyGenAlgorithm keyGenAlg) {
this.name = name;
this.keyGenAlg = keyGenAlg;
nameMap.put(name.toLowerCase(), this);
}
public static final Type DES = new Type("DES", KeyGenAlgorithm.DES);
public static final Type DES3 =
new Type("DESede", KeyGenAlgorithm.DES3);
public static final Type DESede = DES3;
public static final Type RC4 = new Type("RC4", KeyGenAlgorithm.RC4);
public static final Type RC2 = new Type("RC2", KeyGenAlgorithm.RC2);
public static final Type SHA1_HMAC = new Type("SHA1_HMAC",
KeyGenAlgorithm.PBA_SHA1_HMAC);
public static final Type AES = new Type("AES", KeyGenAlgorithm.AES);
public String toString() {
return name;
}
public KeyGenAlgorithm getKeyGenAlg() throws NoSuchAlgorithmException {
if( keyGenAlg == null ) {
throw new NoSuchAlgorithmException(name);
}
return keyGenAlg;
}
public static Type fromName(String name)
throws NoSuchAlgorithmException
{
Object type = nameMap.get(name.toLowerCase());
if( type == null ) {
throw new NoSuchAlgorithmException();
} else {
return (Type) type;
}
}
}
/**
* In PKCS #11, each key can be marked with the operations it will
* be used to perform. Some tokens require that a key be marked for
* an operation before the key can be used to perform that operation;
* other tokens don't care.
*
* instanceof
.
*/
public interface TokenCertificate extends X509Certificate {
/**
* Returns the unique ID of this key. Unique IDs can be used to match
* certificates to keys.
*
* @see org.mozilla.jss.crypto.PrivateKey#getUniqueID
* @deprecated This ID is based on an implementation that might change.
* If this functionality is required, it should be provided in
* another way, such as a function that directly matches a cert and
* key.
*/
public abstract byte[] getUniqueID();
/**
* Returns the CryptoToken that owns this certificate. Cryptographic
* operations with this key may only be performed on the token that
* owns the key.
*/
public abstract CryptoToken getOwningToken();
}
jss-4.4.3/jss/org/mozilla/jss/crypto/TokenException.java 0000664 0000000 0000000 00000001222 13261450000 0023263 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* This class indicates that an unknown error occurred on a CryptoToken.
* The nature of CryptoTokens makes such unpredictable errors possible.
* For example, a smartcard could be yanked out of its slot in the middle
* of a cryptographic operation.
*/
public class TokenException extends Exception {
public TokenException() { super(); }
public TokenException(String mesg) {
super(mesg);
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/TokenRuntimeException.java 0000664 0000000 0000000 00000001256 13261450000 0024636 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* This class indicates that an unknown error occurred on a CryptoToken.
* The nature of CryptoTokens makes such unpredictable errors possible.
* For example, a smartcard could be yanked out of its slot in the middle
* of a cryptographic operation.
*/
public class TokenRuntimeException extends RuntimeException {
public TokenRuntimeException() { super(); }
public TokenRuntimeException(String mesg) {
super(mesg);
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/TokenSupplier.java 0000664 0000000 0000000 00000001411 13261450000 0023130 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* An interface that allows providers to access CryptoManager without actually
* knowing about CryptoManager. This is necessary to prevent cyclic
* dependencies. CryptoManager knows about the providers, so the providers
* can't know about CryptoManager. Instead, CryptoManager implements
* this interface.
*/
public interface TokenSupplier {
public CryptoToken getInternalCryptoToken();
public JSSSecureRandom getSecureRNG();
public CryptoToken getThreadToken();
public void setThreadToken(CryptoToken token);
}
jss-4.4.3/jss/org/mozilla/jss/crypto/TokenSupplierManager.java 0000664 0000000 0000000 00000001644 13261450000 0024433 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* The org.mozilla.jss.provider package comes before CryptoManager in
* the dependency list, so this class is used to allow them to access
* CryptoManager sneakily. When CryptoManager initializes, it registers
* itself as a token supplier with setTokenSupplier
. Then
* the providers call getTokenSupplier
when they need to use
* CryptoManager. CryptoManager implements the TokenSupplier interface.
*/
public class TokenSupplierManager {
static private TokenSupplier supplier;
static public void setTokenSupplier(TokenSupplier ts) {
supplier = ts;
}
static public TokenSupplier getTokenSupplier() {
return supplier;
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/Tunnel.java 0000664 0000000 0000000 00000001127 13261450000 0021575 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
/**
* This is a private JSS class that allows the pkcs11 package access
* to some of the
* package methods in the crypto package. A friend declaration would
* have been ideal.
*/
public class Tunnel {
protected static Signature
ConstructSignature( SignatureAlgorithm alg, SignatureSpi engine) {
return new Signature(alg, engine);
}
}
jss-4.4.3/jss/org/mozilla/jss/crypto/X509Certificate.java 0000664 0000000 0000000 00000002571 13261450000 0023144 0 ustar 00root root 0000000 0000000 /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.jss.crypto;
import java.security.Principal;
import java.math.BigInteger;
/**
* Certificates handled by JSS. All certificates handled by JSS are
* of this type.
*/
public interface X509Certificate
{
/**
* Returns the DER encoding of this certificate.
*/
public byte[] getEncoded()
throws java.security.cert.CertificateEncodingException;
/**
* Returns the possibly-null nickname of this certificate.
*/
public abstract String getNickname();
/**
* Extracts the Public Key from this certificate.
*/
public abstract java.security.PublicKey getPublicKey();
/**
* Returns the RFC 1485 ASCII encoding of the Subject Name.
*/
public abstract Principal
getSubjectDN();
/**
* Returns the RFC 1485 ASCII encoding of the issuer's Subject Name.
*/
public abstract Principal
getIssuerDN();
/**
* Returns the serial number of this certificate.
*/
public abstract BigInteger
getSerialNumber();
/**
* @return the version number of this X.509 certificate.
* 0 means v1, 1 means v2, 2 means v3.
*/
public abstract int
getVersion();
}
jss-4.4.3/jss/org/mozilla/jss/crypto/config.mk 0000664 0000000 0000000 00000000420 13261450000 0021256 0 ustar 00root root 0000000 0000000 #
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
TARGETS=$(LIBRARY)
SHARED_LIBRARY=
IMPORT_LIBRARY=
NO_MD_RELEASE = 1
jss-4.4.3/jss/org/mozilla/jss/crypto/manifest.mn 0000664 0000000 0000000 00000001161 13261450000 0021625 0 ustar 00root root 0000000 0000000 #
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
CORE_DEPTH = ../../../..
MODULE = jss
NS_USE_JDK = 1
REQUIRES = nspr20 nss
PACKAGE = org/mozilla/jss/crypto
PRIVATE_EXPORTS = \
Algorithm.h \
$(NULL)
CSRCS = Algorithm.c \
PQGParams.c \
SecretDecoderRing.c \
$(NULL)
LIBRARY_NAME = jsscrypto
jss-4.4.3/jss/org/mozilla/jss/crypto/package.html 0000664 0000000 0000000 00000000475 13261450000 0021753 0 ustar 00root root 0000000 0000000