View Javadoc

1   package fr.in2p3.jsaga.adaptor.security;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.security.PrivateKey;
6   import java.security.cert.X509Certificate;
7   import java.text.ParseException;
8   import java.util.Map;
9   
10  import org.bouncycastle.openssl.PasswordFinder;
11  import org.globus.common.Version;
12  import org.globus.gsi.CredentialException;
13  import org.globus.gsi.GSIConstants;
14  import org.globus.gsi.GSIConstants.CertificateType;
15  import org.globus.gsi.X509Credential;
16  import org.globus.gsi.bc.BouncyCastleCertProcessingFactory;
17  import org.globus.gsi.gssapi.GlobusGSSCredentialImpl;
18  import org.globus.gsi.util.CertificateLoadUtil;
19  import org.globus.util.Util;
20  import org.ietf.jgss.GSSCredential;
21  import org.ietf.jgss.GSSException;
22  import org.ogf.saga.context.Context;
23  import org.ogf.saga.error.BadParameterException;
24  import org.ogf.saga.error.IncorrectStateException;
25  import org.ogf.saga.error.NoSuccessException;
26  
27  import fr.in2p3.jsaga.adaptor.base.usage.UDuration;
28  
29  /* ***************************************************
30  * *** Centre de Calcul de l'IN2P3 - Lyon (France) ***
31  * ***             http://cc.in2p3.fr/             ***
32  * ***************************************************
33  * File:   GlobusProxyFactory
34  * Author: Sylvain Reynaud (sreynaud@in2p3.fr)
35  * Date:   9 aout 2007
36  * ***************************************************
37  * Description:                                      */
38  /**
39   *
40   */
41  public class GlobusProxyFactory {
42      public static final int OID_OLD = 2;
43      public static final int OID_GLOBUS = 3;    // default
44      public static final int OID_RFC3820 = 4;
45      
46      private static final int PROXY_BITS = 1024;
47      private static final int DEFAULT_PROXY_LIFETIME = 3600 * 12;
48      
49      protected static final int CERTIFICATE_PEM = 0;
50      protected static final int CERTIFICATE_PKCS12 = 1;
51      
52      private X509Credential m_userCredential = null;
53      private String m_proxyFile = "";
54      private int m_proxyLifetime = 0;
55      private CertificateType m_proxyType = null;
56      private String m_cadir = null;
57  
58      public GlobusProxyFactory(Map attributes, int certificateFormat) throws BadParameterException, ParseException {
59          // required attributes
60      	String passphrase = (String) attributes.get(Context.USERPASS);        
61          m_cadir = (String) attributes.get(Context.CERTREPOSITORY);
62          m_proxyFile = (String) attributes.get(Context.USERPROXY);
63          
64          if ("".equals(passphrase)) {
65              passphrase = null;
66          }
67          
68          final char[] pwd;
69          if(passphrase != null){
70          	pwd = passphrase.toCharArray();
71          }else{
72          	pwd = null;
73          }
74          switch(certificateFormat) {
75  	        case CERTIFICATE_PEM:
76  	            String userCert = (String) attributes.get(Context.USERCERT);
77  	            String userKey = (String) attributes.get(Context.USERKEY);
78  				try {
79  					X509Certificate[] x509Certificates = CertificateLoadUtil.loadCertificates(userCert);
80  					PrivateKey privateKey = CertificateLoadUtil.loadPrivateKey(userKey, new PasswordFinder() {
81  						public char[] getPassword() {
82  							return pwd;
83  						}
84  					});
85  					m_userCredential =  new X509Credential(privateKey, x509Certificates);
86  				} catch (Exception e) {
87  					throw new BadParameterException("Unable to load the provided pems files (cert: '" + userCert + "', key: '" + userKey, e);
88  				}
89  	            break;
90  	        case CERTIFICATE_PKCS12:
91  	            String pkcs12 = (String) attributes.get(GlobusContext.USERCERTKEY);
92  				try {
93  					m_userCredential =  CertificateLoadUtil.loadKeystore(pkcs12, passphrase != null ? passphrase.toCharArray() : null, null, null, "PKCS12");
94  				} catch (Exception e) {
95  					throw new BadParameterException("Unable to load the provided pkcs12 file (" + pkcs12 + ")");
96  				}
97  	            break;
98              default:
99                  throw new BadParameterException("Invalid case, either PEM or PKCS12 certificates is supported");
100         }
101         
102         // optional attributes
103         if (attributes.containsKey(Context.LIFETIME)) {
104         	m_proxyLifetime = UDuration.toInt(attributes.get(Context.LIFETIME));
105         }else{
106         	m_proxyLifetime = DEFAULT_PROXY_LIFETIME;
107         }
108         boolean limited = false;
109         if (attributes.containsKey(GlobusContext.DELEGATION)) {
110             limited = ((String)attributes.get(GlobusContext.DELEGATION)).equalsIgnoreCase("limited");
111         }
112         int oid = ProxyTypeMap.toProxyType((String)attributes.get(GlobusContext.PROXYTYPE));
113         switch(oid) {
114             case OID_OLD:
115             	m_proxyType = (limited) ?
116                         GSIConstants.CertificateType.GSI_2_LIMITED_PROXY :
117                         GSIConstants.CertificateType.GSI_2_PROXY;
118                 break;
119             case OID_GLOBUS:
120             	m_proxyType = (limited) ?
121                         GSIConstants.CertificateType.GSI_3_LIMITED_PROXY :
122                         GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY;
123                 break;
124             case OID_RFC3820:
125             	m_proxyType = (limited) ?
126                         GSIConstants.CertificateType.GSI_4_LIMITED_PROXY :
127                         GSIConstants.CertificateType.GSI_4_IMPERSONATION_PROXY;
128                 break;
129         }
130     }
131 
132     public GSSCredential createProxy() throws IncorrectStateException, NoSuccessException {
133     	BouncyCastleCertProcessingFactory bouncyCastleCertProcessingFactory = BouncyCastleCertProcessingFactory.getDefault();    	
134     	X509Credential proxy;
135 		try {
136 			proxy = bouncyCastleCertProcessingFactory.createCredential(m_userCredential.getCertificateChain(), m_userCredential.getPrivateKey(), PROXY_BITS, m_proxyLifetime, m_proxyType);
137 		} catch (Exception e) {
138 			throw new NoSuccessException("Unable to generate the user proxy", e);
139 		}
140         try {
141 			proxy.verify(m_cadir);
142 		} catch (CredentialException e) {
143 			if(proxy.getTimeLeft() < 0){
144 				throw new IncorrectStateException("Your certificate is expired", e);
145 			}else{
146 				throw new NoSuccessException("Proxy verification failed", e);
147 			}
148 		}
149         try {
150         	GlobusGSSCredentialImpl globusGSSCredentialImpl = new GlobusGSSCredentialImpl(proxy, GSSCredential.INITIATE_ONLY);
151         	proxy.writeToFile(new File(m_proxyFile));
152         	Util.setFilePermissions(m_proxyFile, 600);
153         	return globusGSSCredentialImpl;
154         } catch (GSSException e) {
155             throw new NoSuccessException("Proxy convertion failed", e);
156         } catch (CredentialException e) {
157         	throw new NoSuccessException("Unable to save the generated proxy in '" +m_proxyFile + "'", e);
158 		} catch (IOException e) {
159 			throw new NoSuccessException("Unable to save the generated proxy in '" +m_proxyFile + "'", e);
160 		}
161     }
162     
163     public String getVersion() {
164         return Version.getVersion();
165     }
166 }