FileDocCategorySizeDatePackage
DigitalSignature.javaAPI DocAndroid 1.5 API7727Wed May 06 22:41:06 BST 2009org.apache.harmony.xnet.provider.jsse

DigitalSignature

public class DigitalSignature extends Object
This class represents Signature type, as descrybed in TLS v 1.0 Protocol specification, 7.4.3. It allow to init, update and sign hash. Hash algorithm depends on SignatureAlgorithm. select (SignatureAlgorithm) { case anonymous: struct { }; case rsa: digitally-signed struct { opaque md5_hash[16]; opaque sha_hash[20]; }; case dsa: digitally-signed struct { opaque sha_hash[20]; }; } Signature; Digital signing description see in TLS spec., 4.7. (http://www.ietf.org/rfc/rfc2246.txt)

Fields Summary
private MessageDigest
md5
private MessageDigest
sha
private Signature
signature
private Cipher
cipher
private byte[]
md5_hash
private byte[]
sha_hash
Constructors Summary
public DigitalSignature(int keyExchange)
Create Signature type

param
keyExchange

     
              
       
        try { 
            if (keyExchange == CipherSuite.KeyExchange_RSA_EXPORT ||
                    keyExchange == CipherSuite.KeyExchange_RSA ||
                    keyExchange == CipherSuite.KeyExchange_DHE_RSA ||
                    keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT) {
                // SignatureAlgorithm is rsa
                md5 = MessageDigest.getInstance("MD5");
                sha = MessageDigest.getInstance("SHA-1");
                cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            } else if (keyExchange == CipherSuite.KeyExchange_DHE_DSS ||
                    keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT ) {
                // SignatureAlgorithm is dsa
                sha = MessageDigest.getInstance("SHA-1");
                signature = Signature.getInstance("NONEwithDSA");
// The Signature should be empty in case of anonimous signature algorithm:
//            } else if (keyExchange == CipherSuite.KeyExchange_DH_anon ||
//                    keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) {            
//
            }
        } catch (Exception e) {
            throw new AlertException(
                    AlertProtocol.INTERNAL_ERROR,
                    new SSLException(
                            "INTERNAL ERROR: Unexpected exception on digital signature",
                            e));
        }    
            
    
Methods Summary
public voidinit(java.security.PrivateKey key)
Initiate Signature type by private key

param
key

        try {
            if (signature != null) {
                signature.initSign(key);
            } else if (cipher != null) {
                cipher.init(Cipher.ENCRYPT_MODE, key);
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    
public voidinit(java.security.cert.Certificate cert)
Initiate Signature type by certificate

param
cert

        try {
            if (signature != null) {
                signature.initVerify(cert);
            } else if (cipher != null) {
                cipher.init(Cipher.DECRYPT_MODE, cert);
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    
public voidsetMD5(byte[] data)
Sets MD5 hash

param
data

        md5_hash = data;    
    
public voidsetSHA(byte[] data)
Sets SHA hash

param
data

        sha_hash = data;    
    
public byte[]sign()
Sign hash

return
Signature bytes

        try {
            if (md5 != null && md5_hash == null) {
                md5_hash = new byte[16];
                md5.digest(md5_hash, 0, md5_hash.length);
            }    
            if (md5_hash != null) {
                if (signature != null) {
                    signature.update(md5_hash);
                } else if (cipher != null) {
                    cipher.update(md5_hash);
                }
            }
            if (sha != null && sha_hash == null) {
                sha_hash = new byte[20];
                sha.digest(sha_hash, 0, sha_hash.length);
            }
            if (sha_hash != null) {
                if (signature != null) {
                    signature.update(sha_hash);
                } else if (cipher != null) {
                    cipher.update(sha_hash);
                }
            }
            if (signature != null) {
                return signature.sign();
            } else if (cipher != null) {
                return cipher.doFinal();
            } 
            return new byte[0];
        } catch (Exception e){
            e.printStackTrace();
            return new byte[0];
        }    
    
public voidupdate(byte[] data)
Update Signature hash

param
data

        try {
            if (sha != null) {
                sha.update(data);
            }
            if (md5 != null) {
                md5.update(data);
            }
        } catch (Exception e){
            e.printStackTrace();
        }        
    
public booleanverifySignature(byte[] data)
Verifies the signature data.

param
data - the signature bytes
return
true if verified

        try {
            if (signature != null) {
                return signature.verify(data);
            } else if (cipher != null) {
                byte[] decrypt = cipher.doFinal(data);
                byte[] md5_sha;
                if (md5_hash != null && sha_hash != null) {
                    md5_sha = new byte[md5_hash.length + sha_hash.length];
                    System.arraycopy(md5_hash, 0, md5_sha, 0, md5_hash.length);
                    System.arraycopy(sha_hash, 0, md5_sha, md5_hash.length, sha_hash.length);
                } else if (md5_hash != null) {
                    md5_sha = md5_hash;
                } else {
                    md5_sha = sha_hash;
                }
                if (Arrays.equals(decrypt, md5_sha)) {
                    return true;
                } else {
                    return false;
                }
            } else if (data == null || data.length == 0) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e){
                e.printStackTrace();
                return false;
        }