Package com.subgraph.orchid.crypto

Source Code of com.subgraph.orchid.crypto.TorPublicKey

package com.subgraph.orchid.crypto;

import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.interfaces.RSAPublicKey;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import com.subgraph.orchid.TorException;
import com.subgraph.orchid.data.HexDigest;
import com.subgraph.orchid.misc.Utils;

/**
* This class wraps the RSA public keys used in the Tor protocol.
*/
public class TorPublicKey {
  static public TorPublicKey createFromPEMBuffer(String buffer) {
    return new TorPublicKey(buffer);
  }

  private final String pemBuffer;
  private RSAPublicKey key;

  private byte[] rawKeyBytes = null;
  private HexDigest keyFingerprint = null;

  private TorPublicKey(String pemBuffer) {
    this.pemBuffer = pemBuffer;
    this.key = null;
  }

  public TorPublicKey(RSAPublicKey key) {
    this.pemBuffer = null;
    this.key = key;
  }

  private synchronized RSAPublicKey getKey() {
    if(key != null) {
      return key;
    } else if(pemBuffer != null) {
      final RSAKeyEncoder encoder = new RSAKeyEncoder();
      try {
        key = encoder.parsePEMPublicKey(pemBuffer);
      } catch (GeneralSecurityException e) {
        throw new IllegalArgumentException("Failed to parse PEM encoded key: "+ e);
      }
    }
    return key;
  }

  public synchronized byte[] getRawBytes() {
    if(rawKeyBytes == null) {
      final RSAKeyEncoder encoder = new RSAKeyEncoder();
      rawKeyBytes = encoder.getPKCS1Encoded(getKey());
    }
    return rawKeyBytes;
  }

  public synchronized HexDigest getFingerprint() {
    if(keyFingerprint == null) {
      keyFingerprint = HexDigest.createDigestForData(getRawBytes());
    }
    return keyFingerprint;
  }

  public boolean verifySignature(TorSignature signature, HexDigest digest) {
    return verifySignatureFromDigestBytes(signature, digest.getRawBytes());
  }

  public boolean verifySignature(TorSignature signature, TorMessageDigest digest) {
    return verifySignatureFromDigestBytes(signature, digest.getDigestBytes());
  }

  public boolean verifySignatureFromDigestBytes(TorSignature signature, byte[] digestBytes) {
    final Cipher cipher = createCipherInstance();
    try {
      byte[] decrypted = cipher.doFinal(signature.getSignatureBytes());
      return Utils.constantTimeArrayEquals(decrypted, digestBytes);
    } catch (IllegalBlockSizeException e) {
      throw new TorException(e);
    } catch (BadPaddingException e) {
      throw new TorException(e);
    }
  }

  private Cipher createCipherInstance() {
    try {
      Cipher cipher = getCipherInstance();
      cipher.init(Cipher.DECRYPT_MODE, getKey());
      return cipher;
    } catch (InvalidKeyException e) {
      throw new TorException(e);
    }
  }

  private Cipher getCipherInstance() {
    try {
      try {
        return Cipher.getInstance("RSA/ECB/PKCS1Padding", "SunJCE");
      } catch (NoSuchProviderException e) {
        return Cipher.getInstance("RSA/ECB/PKCS1Padding");
      }
    } catch (NoSuchAlgorithmException e) {
      throw new TorException(e);
    } catch (NoSuchPaddingException e) {
      throw new TorException(e);
    }
  }
 
  public RSAPublicKey getRSAPublicKey() {
    return getKey();
  }

  public String toString() {
    return "Tor Public Key: " + getFingerprint();
  }

  public boolean equals(Object o) {
    if(!(o instanceof TorPublicKey))
      return false;
    final TorPublicKey other = (TorPublicKey) o;
    return other.getFingerprint().equals(getFingerprint());
  }

  public int hashCode() {
    return getFingerprint().hashCode();
  }
}
TOP

Related Classes of com.subgraph.orchid.crypto.TorPublicKey

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.