
org.globus.tools.ProxyInit Maven / Gradle / Ivy
The newest version!
/*
* Copyright 1999-2010 University of Chicago
*
* Licensed 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.globus.tools;
import org.globus.gsi.util.CertificateLoadUtil;
import org.globus.gsi.util.CertificateUtil;
import org.globus.gsi.util.ProxyCertificateUtil;
import org.globus.gsi.trustmanager.X509ProxyCertPathValidator;
import org.globus.gsi.stores.ResourceSigningPolicyStore;
import org.globus.gsi.stores.Stores;
import org.globus.gsi.X509ProxyCertPathParameters;
import org.globus.gsi.provider.GlobusProvider;
import java.security.Security;
import java.util.HashMap;
import java.util.Map;
import java.security.cert.CertStore;
import java.security.KeyStore;
import org.globus.gsi.X509ExtensionSet;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPath;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.EOFException;
import java.io.File;
import org.globus.common.CoGProperties;
import org.globus.common.Version;
import org.globus.gsi.OpenSSLKey;
import org.globus.gsi.CertUtil;
import org.globus.gsi.GlobusCredential;
import org.globus.gsi.GSIConstants;
import org.globus.gsi.bc.BouncyCastleOpenSSLKey;
import org.globus.gsi.bc.BouncyCastleCertProcessingFactory;
import org.globus.gsi.proxy.ext.ProxyPolicy;
import org.globus.gsi.proxy.ext.ProxyCertInfo;
import org.globus.gsi.proxy.ext.ProxyCertInfoExtension;
import org.globus.gsi.proxy.ext.GlobusProxyCertInfoExtension;
import org.globus.gsi.proxy.ProxyPolicyHandler;
import org.globus.util.Util;
/* ###########################################################################
* This is a command-line tool and was specifically designed to be used as so.
* Do not use it as a library.
* ######################################################################## */
/**
* Initializes/creates a new globus proxy. This is a command-line tool. Please
* do not use it as a library.
*/
public abstract class ProxyInit {
static {
Security.addProvider(new GlobusProvider());
}
public static final String GENERIC_POLICY_OID = "1.3.6.1.4.1.3536.1.1.1.8";
private static final String message =
"\n" +
"Syntax: java ProxyInit [options]\n" +
" java ProxyInit -help\n\n" +
" Options:\n" +
" -help | -usage\t\tDisplays usage.\n" +
" -version\t\t\tDisplays version.\n" +
" -debug\t\t\tEnables extra debug output.\n" +
" -verify\t\t\tPerforms proxy verification tests (default).\n" +
" -pwstdin\t\t\tAllows passphrase from stdin.\n" +
" -noverify\t\t\tDisables proxy verification tests.\n" +
" -quiet | -q\t\t\tQuiet mode, minimal output\n" +
" -limited\t\t\tCreates a limited proxy.\n" +
" -independent\t\tCreates a independent globus proxy.\n" +
" -old\t\t\tCreates a legacy globus proxy.\n" +
" -valid \t\tProxy is valid for S seconds (default:12 " +
"hours)\n" +
" -valid \tProxy is valid for H hours and M \n" +
" \tminutes. (default: 12 hours)\n" +
" -hours \t\tProxy is valid for H hours (default:12).\n" +
" -bits \t\tNumber of bits in key {512|1024|2048|4096}.\n" +
" -globus\t\t\tPrints user identity in globus format.\n" +
" -policy \tFile containing policy to store in the\n" +
" \tProxyCertInfo extension\n" +
" -pl \t\t\tOID string for the policy language.\n" +
" -policy-language \tused in the policy file.\n" +
" -path-length \t\tAllow a chain of at most l proxies to be \n" +
" \t\tgenerated from this one\n" +
" -cert \t\tNon-standard location of user certificate\n" +
" -key \t\tNon-standard location of user key\n" +
" -out \t\tNon-standard location of new proxy cert.\n" +
" -pkcs11\t\t\tEnables the PKCS11 support module. The\n" +
" \t\t\t-cert and -key arguments are used as labels\n" +
" \t\t\tto find the credentials on the device.\n" +
" -rfc\t\t\tCreates RFC 3820 compliant proxy. (Default)\n" +
" -draft\t\t\tCreates RFC draft compliant proxy\n";
protected X509Certificate[] certificates;
protected int bits = 512;
protected int lifetime = 3600 * 12;
protected ProxyCertInfo proxyCertInfo = null;
protected GSIConstants.CertificateType proxyType;
protected boolean quiet = false;
protected boolean debug = false;
protected boolean stdin = false;
protected GlobusCredential proxy = null;
public abstract void init(String [] args);
public abstract void loadCertificates(String args);
public abstract void loadKey(String arg);
public abstract void sign();
public X509Certificate getCertificate() {
return this.certificates[0];
}
public void dispose() {
}
// verifies the proxy credential
public void verify() throws Exception {
Map handlers = null;
if (proxyCertInfo != null) {
String oid = proxyCertInfo.getProxyPolicy().getPolicyLanguage().getId();
handlers = new HashMap();
handlers.put(oid, new ProxyPolicyHandler() {
public void validate(ProxyCertInfo proxyCertInfo,
CertPath certPath,
int index)
throws CertPathValidatorException {
// ignore policy - this is just for proxy init case
System.out.println("Proxy verify: Ignoring proxy policy");
if (debug) {
String policy =
new String(proxyCertInfo.getProxyPolicy().getPolicy());
System.out.println("Policy:");
System.out.println(policy);
}
}
});
}
KeyStore keyStore = Stores.getDefaultTrustStore();
CertStore crlStore = Stores.getDefaultCRLStore();
ResourceSigningPolicyStore sigPolStore = Stores.getDefaultSigningPolicyStore();
X509ProxyCertPathParameters parameters = new X509ProxyCertPathParameters(keyStore, crlStore, sigPolStore, false, handlers);
X509ProxyCertPathValidator validator = new X509ProxyCertPathValidator();
validator.engineValidate(CertificateUtil.getCertPath(proxy.getCertificateChain()), parameters);
}
public void setBits(int bits) {
this.bits = bits;
}
public void setLifetime(int lifetime) {
this.lifetime = lifetime;
}
/**
* @param proxyType
* @deprecated
*/
public void setProxyType(int proxyType) {
this.proxyType = GSIConstants.CertificateType.get(proxyType);
}
public void setProxyType(GSIConstants.CertificateType proxyType) {
this.proxyType = proxyType;
}
public void setProxyCertInfo(ProxyCertInfo proxyCertInfo) {
this.proxyCertInfo = proxyCertInfo;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
public void setQuiet(boolean quiet) {
this.quiet = quiet;
}
public void setStdin(boolean stdin) {
this.stdin = stdin;
}
public void createProxy(String cert,
String key,
boolean verify,
boolean globusStyle,
String proxyFile) {
init(new String [] {cert, key});
loadCertificates(cert);
if (!quiet) {
String dn = null;
if (globusStyle) {
dn = CertificateUtil.toGlobusID(getCertificate().getSubjectDN());
} else {
dn = getCertificate().getSubjectDN().getName();
}
System.out.println("Your identity: " + dn);
}
loadKey(key);
if (debug) {
System.out.println("Using " + bits + " bits for private key");
}
if (!quiet) {
System.out.println("Creating proxy, please wait...");
}
sign();
if (verify) {
try {
verify();
System.out.println("Proxy verify OK");
} catch(Exception e) {
System.out.println("Proxy verify failed: " + e.getMessage());
if (debug) {
e.printStackTrace();
}
System.exit(-1);
}
}
if (debug) {
System.out.println("Saving proxy to: " + proxyFile);
}
if (!quiet) {
System.out.println("Your proxy is valid until " +
proxy.getCertificateChain()[0].getNotAfter());
}
OutputStream out = null;
try {
File file = Util.createFile(proxyFile);
// set read only permissions
if (!Util.setOwnerAccessOnly(proxyFile)) {
System.err.println("Warning: Please check file permissions for your proxy file.");
}
out = new FileOutputStream(file);
// write the contents
proxy.save(out);
} catch (Exception e) {
System.err.println("Failed to save proxy to a file: " +
e.getMessage());
System.exit(-1);
} finally {
if (out != null) {
try { out.close(); } catch(Exception e) {}
}
}
dispose();
}
public static void main(String args[]) {
int bits = 512;
int lifetime = 3600 * 12;
boolean debug = false;
boolean quiet = false;
boolean verify = true;
boolean pkcs11 = false;
boolean limited = false;
int pathLen = -1;
GSIConstants.CertificateType proxyType = GSIConstants.CertificateType.UNDEFINED;
// 0 is old, 1 is Globus (draft compliant) oid, 2 is rfc oid
int oid = 2;
String policyLanguage = null;
String policyFile = null;
boolean stdin = false;
boolean independent = false;
CoGProperties properties = CoGProperties.getDefault();
boolean globusStyle = false;
String proxyFile = properties.getProxyFile();
String keyFile = null;
String certFile = null;
for (int i = 0; i < args.length; i++) {
if (args[i].equalsIgnoreCase("-hours")) {
if (i+1 >= args.length) {
argError("-hours argument missing");
}
lifetime = 3600 * Integer.parseInt(args[++i]);
} else if (args[i].equalsIgnoreCase("-bits")) {
if (i+1 >= args.length) {
argError("-bits argument missing");
}
bits = Integer.parseInt(args[++i]);
} else if (args[i].equalsIgnoreCase("-pwstdin")) {
stdin = true;
} else if (args[i].equalsIgnoreCase("-limited")) {
limited = true;
} else if (args[i].equalsIgnoreCase("-independent")) {
independent = true;
} else if (args[i].equalsIgnoreCase("-old")) {
oid = 0;
} else if (args[i].equalsIgnoreCase("-path-length")) {
if (i+1 >= args.length) {
argError("-path-length argument missing");
}
pathLen = Integer.parseInt(args[++i]);
} else if (args[i].equalsIgnoreCase("-pl") ||
args[i].equalsIgnoreCase("-policy-language")) {
if (i+1 >= args.length) {
argError("-policy-language argument missing");
}
policyLanguage = args[++i];
} else if (args[i].equalsIgnoreCase("-policy")) {
if (i+1 >= args.length) {
argError("-policy argument missing");
}
policyFile = args[++i];
} else if (args[i].equalsIgnoreCase("-debug")) {
debug = true;
} else if (args[i].equalsIgnoreCase("-verify")) {
verify = true;
} else if (args[i].equalsIgnoreCase("-noverify")) {
verify = false;
} else if (args[i].equalsIgnoreCase("-out")) {
if (i+1 >= args.length) {
argError("-out argument missing");
}
proxyFile = args[++i];
} else if (args[i].equals("-q") ||
args[i].equalsIgnoreCase("-quiet")) {
quiet = true;
} else if (args[i].equalsIgnoreCase("-globus")) {
globusStyle = true;
} else if (args[i].equalsIgnoreCase("-pkcs11")) {
pkcs11 = true;
} else if (args[i].equalsIgnoreCase("-key")) {
if (i+1 >= args.length) {
argError("-key argument missing");
}
keyFile = args[++i];
} else if (args[i].equalsIgnoreCase("-cert")) {
if (i+1 >= args.length) {
argError("-cert argument missing");
}
certFile = args[++i];
} else if (args[i].equalsIgnoreCase("-valid")) {
String validity = args[++i];
int delimiterIndex = validity.indexOf(":");
if (delimiterIndex == -1) {
lifetime = Integer.parseInt(validity);
} else {
String hours = validity.substring(0, delimiterIndex);
String minutes = validity.substring(delimiterIndex+1,
validity.length());
int hoursInt = Integer.parseInt(hours);
int minsInt = Integer.parseInt(minutes);
lifetime = (minsInt * 60) + (hoursInt * 60 * 60);
}
} else if (args[i].equalsIgnoreCase("-version")) {
System.err.println(Version.getVersion());
System.exit(1);
} else if (args[i].equalsIgnoreCase("-help") ||
args[i].equalsIgnoreCase("-usage")) {
System.err.println(message);
System.exit(1);
} else if (args[i].equalsIgnoreCase("-draft")) {
oid = 1;
} else if (args[i].equalsIgnoreCase("-rfc")) {
oid = 2;
} else {
argError("Argument not recognized: " + args[i]);
break;
}
}
if (proxyFile == null) {
error("Proxy file not specified.");
}
boolean restricted = (policyFile != null || policyLanguage != null);
if (independent) {
if (oid == 0) {
error("-old and -independent are exclusive");
}
if (limited) {
error("-limited and -independent are exclusive");
}
if (restricted) {
error("-indepedent and -policy or -pl are exclusive");
}
if (oid == 1) {
proxyType = GSIConstants.CertificateType.GSI_3_INDEPENDENT_PROXY;
} else {
// oid has to be 2
proxyType = GSIConstants.CertificateType.GSI_4_INDEPENDENT_PROXY;
}
}
if (restricted) {
if (oid == 0) {
error("-old and -policy or -pl are exclusive");
}
if (limited) {
error("-limited and -policy or -pl are exclusive");
}
// XXX: check if proxyType == -1?
if (oid == 1) {
proxyType = GSIConstants.CertificateType.GSI_3_RESTRICTED_PROXY;
} else {
// oid has to be 2
proxyType = GSIConstants.CertificateType.GSI_4_RESTRICTED_PROXY;
}
}
if (proxyType == GSIConstants.CertificateType.UNDEFINED) {
if (oid == 1) {
proxyType = (limited) ?
GSIConstants.CertificateType.GSI_3_LIMITED_PROXY :
GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY;
} else if (oid == 2) {
proxyType = (limited) ?
GSIConstants.CertificateType.GSI_4_LIMITED_PROXY :
GSIConstants.CertificateType.GSI_4_IMPERSONATION_PROXY;
} else {
proxyType = (limited) ?
GSIConstants.CertificateType.GSI_2_LIMITED_PROXY :
GSIConstants.CertificateType.GSI_2_PROXY;
}
}
ProxyInit init = null;
if (pkcs11) {
if (keyFile == null) {
if (certFile == null) {
keyFile = certFile = properties.getDefaultPKCS11Handle();
} else {
keyFile = certFile;
}
} else {
if (certFile == null) {
certFile = keyFile;
}
}
try {
Class iClass =
Class.forName("org.globus.pkcs11.tools.PKCS11ProxyInit");
init = (ProxyInit)iClass.newInstance();
} catch (ClassNotFoundException e) {
System.err.println("Error: Failed to load PKCS11 module.");
System.exit(-1);
} catch (InstantiationException e) {
System.err.println("Error: Failed to instantiate PKCS11 module: " + e.getMessage());
System.exit(-1);
} catch (IllegalAccessException e) {
System.err.println("Error: Failed to initialize PKCS11 module: " + e.getMessage());
System.exit(-1);
}
} else {
if (keyFile == null) {
keyFile = properties.getUserKeyFile();
}
if (certFile == null) {
certFile = properties.getUserCertFile();
}
init = new DefaultProxyInit();
}
if (debug) {
System.err.println("Files used: ");
System.err.println(" proxy : " + ((proxyFile == null) ? "none" : proxyFile));
System.err.println(" user key : " + ((keyFile == null) ? "none" : keyFile));
System.err.println(" user cert : " + ((certFile == null) ? "none" : certFile));
}
CertUtil.init();
ProxyCertInfo proxyCertInfo = null;
if ((ProxyCertificateUtil.isGsi3Proxy(proxyType)) ||
(ProxyCertificateUtil.isGsi4Proxy(proxyType))) {
ProxyPolicy policy = null;
if (ProxyCertificateUtil.isLimitedProxy(proxyType)) {
policy = new ProxyPolicy(ProxyPolicy.LIMITED);
} else if (ProxyCertificateUtil.isIndependentProxy(proxyType)) {
policy = new ProxyPolicy(ProxyPolicy.INDEPENDENT);
} else if (ProxyCertificateUtil.isImpersonationProxy(proxyType)) {
// since limited has already been checked, this should work.
policy = new ProxyPolicy(ProxyPolicy.IMPERSONATION);
} else if ((proxyType == GSIConstants.CertificateType.GSI_3_RESTRICTED_PROXY) ||
(proxyType == GSIConstants.CertificateType.GSI_4_RESTRICTED_PROXY)) {
if (policyFile == null) {
error("Policy file required.");
}
if (policyLanguage == null) {
policyLanguage = GENERIC_POLICY_OID;
}
byte [] policyData = null;
try {
policyData = readPolicyFile(policyFile);
} catch (IOException e) {
error("Failed to load policy file: " + e.getMessage());
}
policy = new ProxyPolicy(policyLanguage,
policyData);
} else {
throw new IllegalArgumentException("Invalid proxyType");
}
if (pathLen >= 0) {
proxyCertInfo = new ProxyCertInfo(pathLen, policy);
} else {
proxyCertInfo = new ProxyCertInfo(policy);
}
}
init.setBits(bits);
init.setLifetime(lifetime);
init.setProxyType(proxyType);
init.setProxyCertInfo(proxyCertInfo);
init.setDebug(debug);
init.setQuiet(quiet);
init.setStdin(stdin);
init.createProxy(certFile,
keyFile,
verify,
globusStyle,
proxyFile);
}
private static void argError(String error) {
System.err.println("Error: " + error);
System.err.println();
System.err.println("Usage: java ProxyInit [-help][-limited][-hours H] ...");
System.err.println();
System.err.println("Use -help to display full usage");
System.exit(1);
}
protected static void error(String error) {
System.err.println("Error: " + error);
System.exit(1);
}
private static byte[] readPolicyFile(String file)
throws IOException {
File f = new File(file);
FileInputStream in = new FileInputStream(f);
byte [] data = new byte[(int)f.length()];
int left = data.length;
int off = 0;
int bytes = 0;
try {
while (left > 0) {
bytes = in.read(data, off, left);
if (bytes == -1) {
throw new EOFException();
}
off += bytes;
left -= bytes;
}
} finally {
if (in != null) {
in.close();
}
}
return data;
}
}
class DefaultProxyInit extends ProxyInit {
private PrivateKey userKey = null;
public void init(String [] args) {
verify(args[1], "User key");
verify(args[0], "User certificate");
}
public void verify() throws Exception {
RSAPublicKey pkey = (RSAPublicKey)getCertificate().getPublicKey();
RSAPrivateKey prkey = (RSAPrivateKey)userKey;
if (!pkey.getModulus().equals(prkey.getModulus())) {
throw new Exception("Certificate and private key specified do not match");
}
super.verify();
}
private static void verify(String file, String msg) {
if (file == null) error(msg + " not specified.");
File f = new File(file);
if (!f.exists() || f.isDirectory()) error(msg + " not found.");
}
public void loadCertificates(String arg) {
try {
certificates = CertificateLoadUtil.loadCertificates(arg);
} catch(IOException e) {
System.err.println("Error: Failed to load cert: " + arg);
System.exit(-1);
} catch(GeneralSecurityException e) {
System.err.println("Error: Unable to load user certificate: " +
e.getMessage());
System.exit(-1);
}
}
public void loadKey(String arg) {
try {
OpenSSLKey key = new BouncyCastleOpenSSLKey(arg);
if (key.isEncrypted()) {
String prompt = (quiet) ?
"Enter GRID pass phrase: " :
"Enter GRID pass phrase for this identity: ";
String pwd = (stdin) ?
Util.getInput(prompt) :
Util.getPrivateInput(prompt);
if (pwd == null) {
System.exit(1);
}
key.decrypt(pwd);
}
userKey = key.getPrivateKey();
} catch(IOException e) {
System.err.println("Error: Failed to load key: " + arg);
System.err.println("Error: " + e.getMessage());
System.exit(-1);
} catch(GeneralSecurityException e) {
System.err.println("Error: Wrong pass phrase");
System.err.println("Error: " + e.getMessage());
if (debug) {
e.printStackTrace();
}
System.exit(-1);
}
}
public void sign() {
try {
BouncyCastleCertProcessingFactory factory =
BouncyCastleCertProcessingFactory.getDefault();
X509ExtensionSet extSet = null;
if (proxyCertInfo != null) {
extSet = new X509ExtensionSet();
if (ProxyCertificateUtil.isGsi4Proxy(proxyType)) {
// RFC compliant OID
extSet.add(new ProxyCertInfoExtension(proxyCertInfo));
} else {
// old OID
extSet.add(new GlobusProxyCertInfoExtension(proxyCertInfo));
}
}
proxy = factory.createCredential(certificates,
userKey,
bits,
lifetime,
proxyType.getCode(),
extSet);
} catch (GeneralSecurityException e) {
System.err.println("Failed to create a proxy: " + e.getMessage());
System.exit(-1);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy