KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > core > protocol > xkms > generators > RequestAbstractTypeResponseGenerator


1 /*************************************************************************
2  * *
3  * EJBCA: The OpenSource Certificate Authority *
4  * *
5  * This software is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU Lesser General Public *
7  * License as published by the Free Software Foundation; either *
8  * version 2.1 of the License, or any later version. *
9  * *
10  * See terms of license at gnu.org. *
11  * *
12  *************************************************************************/

13
14 package org.ejbca.core.protocol.xkms.generators;
15
16 import java.math.BigInteger JavaDoc;
17 import java.security.cert.CertificateEncodingException JavaDoc;
18 import java.security.cert.X509Certificate JavaDoc;
19 import java.security.interfaces.RSAPublicKey JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.Date JavaDoc;
22 import java.util.GregorianCalendar JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25
26 import javax.ejb.CreateException JavaDoc;
27 import javax.naming.NamingException JavaDoc;
28 import javax.xml.datatype.DatatypeConfigurationException JavaDoc;
29 import javax.xml.datatype.XMLGregorianCalendar JavaDoc;
30
31 import org.apache.log4j.Logger;
32 import org.ejbca.core.ejb.ca.sign.SernoGenerator;
33 import org.ejbca.core.model.InternalResources;
34 import org.ejbca.core.model.ca.caadmin.CAInfo;
35 import org.ejbca.core.model.ca.certificateprofiles.CertificateProfile;
36 import org.ejbca.core.model.ca.crl.RevokedCertInfo;
37 import org.ejbca.core.model.ca.store.CertificateInfo;
38 import org.ejbca.core.protocol.xkms.common.XKMSConstants;
39 import org.ejbca.util.CertTools;
40 import org.ejbca.util.dn.DNFieldExtractor;
41 import org.w3._2000._09.xmldsig_.KeyInfoType;
42 import org.w3._2000._09.xmldsig_.KeyValueType;
43 import org.w3._2000._09.xmldsig_.RSAKeyValueType;
44 import org.w3._2000._09.xmldsig_.X509DataType;
45 import org.w3._2002._03.xkms_.KeyBindingAbstractType;
46 import org.w3._2002._03.xkms_.KeyBindingType;
47 import org.w3._2002._03.xkms_.ObjectFactory;
48 import org.w3._2002._03.xkms_.RequestAbstractType;
49 import org.w3._2002._03.xkms_.ResultType;
50 import org.w3._2002._03.xkms_.StatusType;
51 import org.w3._2002._03.xkms_.UnverifiedKeyBindingType;
52 import org.w3._2002._03.xkms_.UseKeyWithType;
53 import org.w3._2002._03.xkms_.ValidityIntervalType;
54
55
56
57 /**
58  * Help method that generates the most basic parts of a xkms message
59  * response
60  *
61  *
62  * @author Philip Vendil 2006 sep 27
63  *
64  * @version $Id: RequestAbstractTypeResponseGenerator.java,v 1.4 2007/01/07 19:44:14 herrvendil Exp $
65  */

66
67 public abstract class RequestAbstractTypeResponseGenerator extends BaseResponseGenerator{
68
69     private static Logger log = Logger.getLogger(RequestAbstractTypeResponseGenerator.class);
70     private static final InternalResources intres = InternalResources.getInstance();
71     
72     protected static final BigInteger JavaDoc SERVERRESPONSELIMIT = new BigInteger JavaDoc("30");
73     
74
75     protected RequestAbstractType req;
76     protected ObjectFactory xkmsFactory = new ObjectFactory();
77     protected org.w3._2000._09.xmldsig_.ObjectFactory sigFactory = new org.w3._2000._09.xmldsig_.ObjectFactory();
78     
79     protected String JavaDoc resultMajor = null;
80     protected String JavaDoc resultMinor = null;
81
82     
83     
84     public RequestAbstractTypeResponseGenerator(String JavaDoc remoteIP, RequestAbstractType req){
85       super(remoteIP);
86       this.req = req;
87             
88     }
89     
90
91
92
93     /**
94      * Returns the generated response common data that should be sent back to the client
95      * @return the response
96      */

97     protected void populateResponse(ResultType result, boolean requestVerifies){
98         result.setService(genServiceValue());
99         result.setId(genId());
100         result.setRequestId(req.getId());
101         result.setOpaqueClientData(req.getOpaqueClientData());
102                         
103
104         // Nonce is required for two phase commit
105

106         if(!requestVerifies){
107             resultMajor = XKMSConstants.RESULTMAJOR_SENDER;
108             resultMinor = XKMSConstants.RESULTMINOR_NOAUTHENTICATION;
109         }
110  
111     }
112
113
114     protected int getResponseLimit() {
115         if(req.getResponseLimit() == null || req.getResponseLimit().compareTo(SERVERRESPONSELIMIT) >= 0){
116             return SERVERRESPONSELIMIT.intValue();
117         }
118         
119         return req.getResponseLimit().intValue();
120     }
121
122
123     private String JavaDoc genId() {
124         String JavaDoc id = "";
125         try {
126             id = SernoGenerator.instance().getSerno().toString();
127         } catch (Exception JavaDoc e) {
128             log.error(intres.getLocalizedMessage("xkms.errorgenrespid"),e);
129         }
130         return "_" + id;
131     }
132
133
134     private String JavaDoc genServiceValue() {
135         return "http://@httpsserver.hostname@:@httpserver.pubhttp@/ejbca/xkms/xkms";
136     }
137     
138
139     
140     /**
141      * Method used to set the result of the operation
142      */

143     protected void setResult(ResultType result){
144         result.setResultMajor(resultMajor);
145         if(resultMinor != null){
146             result.setResultMinor(resultMinor);
147         }
148     }
149     
150     /**
151      * Method that returns the XKMS KeyUsage Constants that can be applied to the given
152      * X509Certiifcate
153      *
154      * return List<String> of size 0 to 3 of XKMSConstants.KEYUSAGE_ constants.
155      */

156    protected List JavaDoc<String JavaDoc> getCertKeyUsageSpec(X509Certificate JavaDoc cert) {
157        ArrayList JavaDoc<String JavaDoc> retval = new ArrayList JavaDoc<String JavaDoc>();
158        
159        if(cert.getKeyUsage()[CertificateProfile.DATAENCIPHERMENT]){
160            retval.add(XKMSConstants.KEYUSAGE_ENCRYPTION);
161        }
162        if(cert.getKeyUsage()[CertificateProfile.DIGITALSIGNATURE]
163           || cert.getKeyUsage()[CertificateProfile.KEYENCIPHERMENT]){
164            retval.add(XKMSConstants.KEYUSAGE_EXCHANGE);
165        }
166        if(XKMSConfig.signatureIsNonRep()){
167            if(cert.getKeyUsage()[CertificateProfile.NONREPUDIATION]){
168                retval.add(XKMSConstants.KEYUSAGE_SIGNATURE);
169            }
170        }else{
171              if(cert.getKeyUsage()[CertificateProfile.DIGITALSIGNATURE]){
172                  retval.add(XKMSConstants.KEYUSAGE_SIGNATURE);
173              }
174        }
175            
176        return retval;
177    }
178    
179    /**
180     * Method that determines the UseKeyWith attribute from an X509Certificate
181     * and the requested UseKeyWithAttributes
182     */

183    protected List JavaDoc<UseKeyWithType> genUseKeyWithAttributes(X509Certificate JavaDoc cert, List JavaDoc<UseKeyWithType> reqUsages) throws Exception JavaDoc{
184        ArrayList JavaDoc<UseKeyWithType> retval = new ArrayList JavaDoc();
185        
186        Iterator JavaDoc<UseKeyWithType> iter = reqUsages.iterator();
187        while(iter.hasNext()){
188            UseKeyWithType useKeyWithType = iter.next();
189            DNFieldExtractor altNameExtractor = new DNFieldExtractor(CertTools.getSubjectAlternativeName(cert),DNFieldExtractor.TYPE_SUBJECTALTNAME);
190            String JavaDoc cn = CertTools.getPartFromDN(cert.getSubjectDN().toString(), "CN");
191            
192            
193            if(useKeyWithType.getApplication().equals(XKMSConstants.USEKEYWITH_XKMS)||
194               useKeyWithType.getApplication().equals(XKMSConstants.USEKEYWITH_XKMSPROFILE) ||
195               useKeyWithType.getApplication().equals(XKMSConstants.USEKEYWITH_TLS)){
196                 if(altNameExtractor.getField(DNFieldExtractor.URI, 0).startsWith(useKeyWithType.getIdentifier())){
197                   retval.add(useKeyWithType);
198                 }
199            }
200            if(useKeyWithType.getApplication().equals(XKMSConstants.USEKEYWITH_SMIME)||
201               useKeyWithType.getApplication().equals(XKMSConstants.USEKEYWITH_PGP)){
202                 if(altNameExtractor.getField(DNFieldExtractor.RFC822NAME, 0).startsWith(useKeyWithType.getIdentifier())){
203                       retval.add(useKeyWithType);
204                 }
205            }
206            if(useKeyWithType.getApplication().equals(XKMSConstants.USEKEYWITH_TLSHTTP)){
207                 if(cn.startsWith(useKeyWithType.getIdentifier())){
208                       retval.add(useKeyWithType);
209                 }
210            }
211            if(useKeyWithType.getApplication().equals(XKMSConstants.USEKEYWITH_TLSSMTP)){
212                 if(altNameExtractor.getField(DNFieldExtractor.DNSNAME, 0).startsWith(useKeyWithType.getIdentifier())){
213                       retval.add(useKeyWithType);
214                 }
215            }
216            if(useKeyWithType.getApplication().equals(XKMSConstants.USEKEYWITH_IPSEC)){
217                 if(altNameExtractor.getField(DNFieldExtractor.IPADDRESS, 0).startsWith(useKeyWithType.getIdentifier())){
218                       retval.add(useKeyWithType);
219                 }
220            }
221            if(useKeyWithType.getApplication().equals(XKMSConstants.USEKEYWITH_PKIX)){
222                 if(cert.getSubjectDN().toString().equalsIgnoreCase(CertTools.stringToBCDNString(useKeyWithType.getIdentifier()))){
223                       retval.add(useKeyWithType);
224                 }
225            }
226        }
227        
228     
229        return retval;
230    }
231    
232     /**
233     * Method adding supported response values specified
234     * in the request
235     *
236     * @param certificate to respond
237     */

238    protected KeyBindingAbstractType getResponseValues(KeyBindingAbstractType queryKeyBindingType, X509Certificate JavaDoc cert, boolean validateOrRevokeReq, boolean kRSSCall){
239     UnverifiedKeyBindingType retval = xkmsFactory.createUnverifiedKeyBindingType();
240     if(validateOrRevokeReq || kRSSCall){
241         retval = xkmsFactory.createKeyBindingType();
242         
243         ((KeyBindingType) retval).setStatus(getStatus(cert, kRSSCall));
244     }
245             
246
247     retval.setId("_" + cert.getSerialNumber().toString(16));
248     retval.setValidityInterval(getValidityInterval(cert));
249
250     KeyInfoType keyInfoType = sigFactory.createKeyInfoType();
251
252     if(req.getRespondWith().contains(XKMSConstants.RESPONDWITH_KEYNAME)){
253         String JavaDoc keyName = cert.getSubjectDN().toString();
254         keyInfoType.getContent().add(sigFactory.createKeyName(keyName));
255     }
256
257     if(req.getRespondWith().contains(XKMSConstants.RESPONDWITH_KEYVALUE)){
258         if(cert.getPublicKey() instanceof RSAPublicKey JavaDoc){
259             RSAPublicKey JavaDoc pubKey = (RSAPublicKey JavaDoc) cert.getPublicKey();
260             RSAKeyValueType rSAKeyValueType = sigFactory.createRSAKeyValueType();
261             rSAKeyValueType.setModulus(pubKey.getModulus().toByteArray());
262             rSAKeyValueType.setExponent(pubKey.getPublicExponent().toByteArray());
263             KeyValueType keyValue = sigFactory.createKeyValueType();
264             keyValue.getContent().add(sigFactory.createRSAKeyValue(rSAKeyValueType));
265             keyInfoType.getContent().add(sigFactory.createKeyValue(keyValue));
266         }else{
267             log.error(intres.getLocalizedMessage("xkms.onlyrsakeysupported"));
268             resultMajor = XKMSConstants.RESULTMAJOR_RECIEVER;
269             resultMinor = XKMSConstants.RESULTMINOR_FAILURE;
270         }
271     }
272
273     if(req.getRespondWith().contains(XKMSConstants.RESPONDWITH_X509CERT) ||
274             req.getRespondWith().contains(XKMSConstants.RESPONDWITH_X509CHAIN) ||
275             req.getRespondWith().contains(XKMSConstants.RESPONDWITH_X509CRL)){
276             X509DataType x509DataType = sigFactory.createX509DataType();
277         if(req.getRespondWith().contains(XKMSConstants.RESPONDWITH_X509CERT) && !req.getRespondWith().contains(XKMSConstants.RESPONDWITH_X509CHAIN)){
278             try {
279                 x509DataType.getX509IssuerSerialOrX509SKIOrX509SubjectName().add(sigFactory.createX509DataTypeX509Certificate(cert.getEncoded()));
280             } catch (CertificateEncodingException JavaDoc e) {
281                 log.error(intres.getLocalizedMessage("xkms.errordecodingcert"),e);
282                 resultMajor = XKMSConstants.RESULTMAJOR_RECIEVER;
283                 resultMinor = XKMSConstants.RESULTMINOR_FAILURE;
284             }
285         }
286         if(req.getRespondWith().contains(XKMSConstants.RESPONDWITH_X509CHAIN)){
287             int caid = CertTools.getIssuerDN(cert).hashCode();
288             try {
289                 Iterator JavaDoc iter = getCAAdminSession().getCAInfo(pubAdmin, caid).getCertificateChain().iterator();
290                 while(iter.hasNext()){
291                     X509Certificate JavaDoc next = (X509Certificate JavaDoc) iter.next();
292                     x509DataType.getX509IssuerSerialOrX509SKIOrX509SubjectName().add(sigFactory.createX509DataTypeX509Certificate(next.getEncoded()));
293                 }
294                 x509DataType.getX509IssuerSerialOrX509SKIOrX509SubjectName().add(sigFactory.createX509DataTypeX509Certificate(cert.getEncoded()));
295             } catch (Exception JavaDoc e) {
296                 log.error(intres.getLocalizedMessage("xkms.errorfetchinglastcrl"),e);
297                 resultMajor = XKMSConstants.RESULTMAJOR_RECIEVER;
298                 resultMinor = XKMSConstants.RESULTMINOR_FAILURE;
299             }
300         }
301         if(req.getRespondWith().contains(XKMSConstants.RESPONDWITH_X509CRL)){
302             byte[] crl = null;
303             try {
304                 crl = getCertStoreSession().getLastCRL(pubAdmin, CertTools.getIssuerDN(cert));
305             } catch (Exception JavaDoc e) {
306                 log.error(intres.getLocalizedMessage("xkms.errorfetchinglastcrl"),e);
307                 resultMajor = XKMSConstants.RESULTMAJOR_RECIEVER;
308                 resultMinor = XKMSConstants.RESULTMINOR_FAILURE;
309             }
310             x509DataType.getX509IssuerSerialOrX509SKIOrX509SubjectName().add(sigFactory.createX509DataTypeX509CRL(crl));
311         }
312         keyInfoType.getContent().add(sigFactory.createX509Data(x509DataType));
313         
314     }
315     retval.setKeyInfo(keyInfoType);
316     retval.getKeyUsage().addAll(getCertKeyUsageSpec(cert));
317         try {
318             retval.getUseKeyWith().addAll(genUseKeyWithAttributes(cert, queryKeyBindingType.getUseKeyWith()));
319         } catch (Exception JavaDoc e) {
320             log.error(intres.getLocalizedMessage("xkms.errorextractingusekeyattr"),e);
321             resultMajor = XKMSConstants.RESULTMAJOR_RECIEVER;
322             resultMinor = XKMSConstants.RESULTMINOR_FAILURE;
323             
324         }
325     
326     
327     return retval;
328    }
329    
330     protected ValidityIntervalType getValidityInterval(X509Certificate JavaDoc cert) {
331         ValidityIntervalType valitityIntervalType = xkmsFactory.createValidityIntervalType();
332         try {
333           GregorianCalendar JavaDoc notBeforeGregorianCalendar = new GregorianCalendar JavaDoc();
334           notBeforeGregorianCalendar.setTime(cert.getNotBefore());
335           XMLGregorianCalendar JavaDoc notBeforeXMLGregorianCalendar = javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar(notBeforeGregorianCalendar);
336           notBeforeXMLGregorianCalendar.normalize();
337           valitityIntervalType.setNotBefore(notBeforeXMLGregorianCalendar);
338         
339           GregorianCalendar JavaDoc notAfterGregorianCalendar = new GregorianCalendar JavaDoc();
340           notAfterGregorianCalendar.setTime(cert.getNotAfter());
341           XMLGregorianCalendar JavaDoc notAfterXMLGregorianCalendar = javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar(notAfterGregorianCalendar);
342           notAfterXMLGregorianCalendar.normalize();
343           valitityIntervalType.setNotOnOrAfter(notAfterXMLGregorianCalendar);
344         
345         } catch (DatatypeConfigurationException JavaDoc e) {
346             log.error(intres.getLocalizedMessage("xkms.errorsetvalidityinterval"),e);
347         }
348         
349         
350         return valitityIntervalType;
351     }
352     
353
354     /**
355      * Method that checks the status of the certificate used
356      * in a XKMS validate call.
357      *
358      * @param kRSSCall, regenerated certificate return all valid
359      * @param cert
360      */

361     private StatusType getStatus(X509Certificate JavaDoc cert, boolean kRSSCall) {
362         StatusType retval = xkmsFactory.createStatusType();
363         
364         if(kRSSCall){
365             retval.setStatusValue(XKMSConstants.STATUSVALUE_VALID);
366             retval.getValidReason().add(XKMSConstants.STATUSREASON_VALIDITYINTERVAL);
367             retval.getValidReason().add(XKMSConstants.STATUSREASON_ISSUERTRUST);
368             retval.getValidReason().add(XKMSConstants.STATUSREASON_SIGNATURE);
369             retval.getValidReason().add(XKMSConstants.STATUSREASON_REVOCATIONSTATUS);
370         }else{
371             boolean allValid = true;
372             boolean inValidSet = false;
373
374             //Check validity
375
try{
376                 cert.checkValidity( new Date JavaDoc());
377                 retval.getValidReason().add(XKMSConstants.STATUSREASON_VALIDITYINTERVAL);
378             }catch(Exception JavaDoc e){
379                 retval.getInvalidReason().add(XKMSConstants.STATUSREASON_VALIDITYINTERVAL);
380                 allValid = false;
381                 inValidSet = true;
382             }
383
384             // Check Issuer Trust
385
try{
386                 int caid = CertTools.getIssuerDN(cert).hashCode();
387                 CAInfo cAInfo = getCAAdminSession().getCAInfo(pubAdmin, caid);
388                 if(cAInfo != null){
389                     retval.getValidReason().add(XKMSConstants.STATUSREASON_ISSUERTRUST);
390
391                     // Check signature
392
try{
393                         if(CertTools.verify(cert, cAInfo.getCertificateChain())){
394                             retval.getValidReason().add(XKMSConstants.STATUSREASON_SIGNATURE);
395                         }else{
396                             retval.getInvalidReason().add(XKMSConstants.STATUSREASON_SIGNATURE);
397                             allValid = false;
398                             inValidSet = true;
399                         }
400                     }catch(Exception JavaDoc e){
401                         retval.getInvalidReason().add(XKMSConstants.STATUSREASON_SIGNATURE);
402                         allValid = false;
403                         inValidSet = true;
404                     }
405                 }else{
406                     retval.getInvalidReason().add(XKMSConstants.STATUSREASON_ISSUERTRUST);
407                     retval.getIndeterminateReason().add(XKMSConstants.STATUSREASON_SIGNATURE);
408                     allValid = false;
409                     inValidSet = true;
410                 }
411
412                 // Check RevokationReason
413
CertificateInfo certInfo = getCertStoreSession().getCertificateInfo(pubAdmin, CertTools.getFingerprintAsString(cert));
414                 if(certInfo != null){
415                     if(certInfo.getRevocationReason() == RevokedCertInfo.NOT_REVOKED){
416                         retval.getValidReason().add(XKMSConstants.STATUSREASON_REVOCATIONSTATUS);
417                     }else{
418                         retval.getInvalidReason().add(XKMSConstants.STATUSREASON_REVOCATIONSTATUS);
419                         allValid = false;
420                         inValidSet = true;
421                     }
422                 }else{
423                     retval.getIndeterminateReason().add(XKMSConstants.STATUSREASON_REVOCATIONSTATUS);
424                     allValid = false;
425                 }
426
427
428             }catch(CreateException JavaDoc e){
429                 log.error(intres.getLocalizedMessage("xkms.errorcreatesession"),e);
430                 resultMajor = XKMSConstants.RESULTMAJOR_RECIEVER;
431                 resultMinor = XKMSConstants.RESULTMINOR_FAILURE;
432             } catch (ClassCastException JavaDoc e) {
433                 log.error(intres.getLocalizedMessage("xkms.errorcreatesession"),e);
434                 resultMajor = XKMSConstants.RESULTMAJOR_RECIEVER;
435                 resultMinor = XKMSConstants.RESULTMINOR_FAILURE;
436             } catch (NamingException JavaDoc e) {
437                 log.error(intres.getLocalizedMessage("xkms.errorcreatesession"),e);
438                 resultMajor = XKMSConstants.RESULTMAJOR_RECIEVER;
439                 resultMinor = XKMSConstants.RESULTMINOR_FAILURE;
440             }
441
442             if(allValid){
443                 retval.setStatusValue(XKMSConstants.STATUSVALUE_VALID);
444             }else{
445                 if(inValidSet){
446                     retval.setStatusValue(XKMSConstants.STATUSVALUE_INVALID);
447                 }else{
448                     retval.setStatusValue(XKMSConstants.STATUSVALUE_INDETERMINATE);
449                 }
450             }
451
452         }
453         return retval;
454     }
455     
456     
457 }
458
Popular Tags