Package org.apache.uima.ducc.common.crypto

Source Code of org.apache.uima.ducc.common.crypto.Crypto

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.uima.ducc.common.crypto;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

import javax.crypto.Cipher;

import org.apache.uima.ducc.common.utils.AlienFile;
import org.apache.uima.ducc.common.utils.Utils;

public class Crypto implements ICrypto {
 
  private boolean traditional = false;
 
  private String dirDotDucc = ".ducc";
  private String dirDotDuccPermissions  = "0755";
  private String pubFilePermissions = "0755";
  private String pvtFilePermissions = "0700";

  private String user;
  private String dirUserKeys;
  private String filePvt;
  private String filePub;
 
  private int keySize = 2048;
  private String keyType = "RSA";
 
  private Cipher cipher;
 
  public enum AccessType {
    READER,
    WRITER,
  }
 
  public Crypto(String user, String dirHome) throws CryptoException {
    init(user,dirHome,dirDotDucc,AccessType.WRITER);
  }
 
  public Crypto(String user, String dirHome, AccessType accessType) throws CryptoException {
    init(user,dirHome,dirDotDucc,accessType);
  }
 
  public Crypto(String user, String dirHome, String dirSub) throws CryptoException {
    init(user,dirHome,dirSub,AccessType.WRITER);
  }
 
  public Crypto(String user, String dirHome, String dirSub, AccessType accessType) throws CryptoException {
    init(user,dirHome,dirSub,accessType);
  }
 
  private void init(String tgtUser, String dirHome, String dirSub, AccessType accessType) throws CryptoException {
    user = tgtUser;
    dirUserKeys = dirHome+File.separator+dirSub;
    filePub = dirUserKeys+File.separator+"public.key";
    filePvt = dirUserKeys+File.separator+"private.key";
    switch(accessType) {
    case READER:
      break;
    case WRITER:
      createKeys();
      checkKeys();
      break;
    }
    try {
      cipher = Cipher.getInstance(keyType);
    }
    catch(Exception e) {
      throw new CryptoException(e);
    }
  }
 
  public String getPublic() {
    return filePub;
  }
 
  public String getPrivate() {
    return filePvt;
  }
 
  private boolean isMissingKeys() {
    boolean retVal = false;
    try {
      checkFile(filePub);
      checkFile(filePvt);
    }
    catch(Exception e) {
      retVal = true;
    }
    return retVal;
  }
 
  private void createKeys() throws CryptoException {
    try {
      synchronized(Crypto.class) {
        if(isMissingKeys()) {
          mkdir(dirUserKeys, dirDotDuccPermissions);
          KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyType);
          kpg.initialize(keySize);
          KeyPair kp = kpg.genKeyPair();
          KeyFactory keyFactory = KeyFactory.getInstance(keyType);
          RSAPublicKeySpec pub = keyFactory.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);
          // <IBM JDK does not seem to support RSAPrivateKeySpec.class>
          RSAPrivateKeySpec pvt;
          try {
            pvt = keyFactory.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class);
          }
          catch(Exception e) {
            pvt = keyFactory.getKeySpec(kp.getPrivate(), RSAPrivateCrtKeySpec.class);
          }
          // </IBM JDK does not seem to support RSAPrivateKeySpec.class>
          putKeyToFile(filePub, pub.getModulus(), pub.getPublicExponent(),pubFilePermissions);
          putKeyToFile(filePvt, pvt.getModulus(), pvt.getPrivateExponent(),pvtFilePermissions);
        }
      }
    }
    catch(CryptoException e) {
      throw e;
    }
    catch(Exception e) {
      throw new CryptoException(e);
    }
  }
 
  private void checkDir(String fileName) throws CryptoException {
    File file = new File(fileName);
    if(!file.exists()) {
      throw new CryptoException("Directory does not exist: "+fileName);
    }
  }
 
  private void checkFile(String fileName) throws CryptoException {
    File file = new File(fileName);
    if(!file.exists()) {
      throw new CryptoException("File does not exist: "+fileName);
    }
  }
 
  private void checkKeys() throws CryptoException {
    checkDir(dirUserKeys);
    checkFile(filePvt);
    checkFile(filePub);
  }
 
  private void exec(String cmd) throws CryptoException {
    try {
      Process process;
      process = Runtime.getRuntime().exec(cmd);
      process.waitFor();
    }
    catch(Exception e) {
      throw new CryptoException(e);
    }
  }
 
  private void chmod(String fileName, String permissions) throws CryptoException {
    String osName = System.getProperty("os.name");
    if (osName.startsWith("Windows")) {
      // Windows is not supported for running
      // For building, some tests run through this code,
      //   so we bypass doing the chmod on Windows environments
      return;
    }
    try {
      exec("chmod "+permissions+" "+fileName);
    }
    catch(Exception e) {
      throw new CryptoException(e);
    }
  }
 
  private void mkdir(String dir, String permissions) throws CryptoException {
    try {
      File file = new File(dir);
      file.mkdirs();
      chmod(dirUserKeys, permissions);
    }
    catch(Exception e) {
      throw new CryptoException(e);
    }
  }
 
  private void putKeyToFile(String fileName, BigInteger mod, BigInteger exp, String permissions) throws CryptoException {
    try {
      ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
      try {
        oos.writeObject(mod);
        oos.writeObject(exp);
        chmod(fileName, permissions);
      }
      finally {
        oos.close();
      }
    }
    catch(Exception e) {
      throw new CryptoException(e);
    }
  }
 
  public boolean isReadablePrivate() {
    boolean readable = false;
    File file = new File(filePvt);
    readable = file.canRead();
    return readable;
  }
 
  public boolean isReadablePublic() {
    boolean readable = false;
    File file = new File(filePub);
    readable = file.canRead();
    return readable;
  }
 
  private Key getPubicKeyFromFile() throws CryptoException {
    try {
      String fileName = filePub;
      ObjectInputStream ois = null;
      DataInputStream dis = null;
      if(isReadablePublic()) {
        ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(fileName)));
      }
      else {
        String ducc_ling =
            Utils.resolvePlaceholderIfExists(
                System.getProperty("ducc.agent.launcher.ducc_spawn_path"),System.getProperties());
       
        AlienFile alienFile = new AlienFile(user,fileName,ducc_ling);
        dis = alienFile.getDataInputStream();
        ois = new ObjectInputStream(new BufferedInputStream(dis));
      }
      try {
        BigInteger mod = (BigInteger) ois.readObject();
          BigInteger exp = (BigInteger) ois.readObject();
          RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(mod, exp);
         
          if(traditional) {
            KeyFactory keyFactory = KeyFactory.getInstance(keyType);
            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
            return publicKey;
          }
         
          RSAPrivateKeySpec spec = new RSAPrivateKeySpec(publicKeySpec.getModulus(),publicKeySpec.getPublicExponent());
          Key key = KeyFactory.getInstance("RSA").generatePrivate(spec);
         
          return key;
      }
      finally {
        if(ois != null) {
          ois.close();
        }
        if(dis != null) {
          dis.close();
        }
      }
    }
    catch(Throwable t) {
      throw new CryptoException(t);
    }
  }
 
  private Key getPrivateKeyFromFile() throws CryptoException {
    try {
      String fileName = filePvt;
      ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(fileName)));
      try {
        BigInteger mod = (BigInteger) ois.readObject();
          BigInteger exp = (BigInteger) ois.readObject();
          RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(mod, exp);
         
          if(traditional) {
            KeyFactory keyFactory = KeyFactory.getInstance(keyType);
            PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
            return privateKey;
          }
         
          RSAPublicKeySpec spec = new RSAPublicKeySpec(privateKeySpec.getModulus(),privateKeySpec.getPrivateExponent());
          Key key = KeyFactory.getInstance("RSA").generatePublic(spec);

          return key;
      }
      finally {
        ois.close();
      }
    }
    catch(Exception e) {
      throw new CryptoException(e);
    }
  }
 
  private byte[] o2b(Object object) throws CryptoException {
    byte[] byteArray;
    try {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      ObjectOutput oo = new ObjectOutputStream(bos);  
      try {
        oo.writeObject(object);
        byteArray = bos.toByteArray();
      }
      finally {
        oo.close();
        bos.close();
      }
    }
    catch(Exception e) {
      throw new CryptoException(e);
    }
    return byteArray;
  }
 
  private Object b2o(byte[] byteArray) throws CryptoException {
    Object object;
    try {
      ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
      ObjectInput oi = new ObjectInputStream(bis);  
      try {
        object = oi.readObject();
      }
      finally {
        oi.close();
        bis.close();
      }
    }
    catch(Exception e) {
      throw new CryptoException(e);
    }
    return object;
  }
 

  public byte[] encrypt(Object o) throws CryptoException {
    try {
      Key key = getPrivateKeyFromFile();
      cipher.init(Cipher.ENCRYPT_MODE, key);
      return cipher.doFinal(o2b(o));
      }
    catch(Exception e) {
      throw new CryptoException(e);
    }
  }
 

  public Object decrypt(byte[] byteArray) throws CryptoException {
    try {
      Key key = getPubicKeyFromFile();
      cipher.init(Cipher.DECRYPT_MODE, key);
      return b2o(cipher.doFinal(byteArray));
      }
    catch(Exception e) {
      throw new CryptoException(e);
    }
  }
 
}
TOP

Related Classes of org.apache.uima.ducc.common.crypto.Crypto

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.