View Javadoc

1   package es.caib.signatura.impl;
2   
3   import java.io.IOException;
4   import java.io.InputStream;
5   import java.io.Serializable;
6   import java.security.cert.X509Certificate;
7   import java.util.Date;
8   
9   import es.caib.signatura.api.SignatureVerifyException;
10  
11  import es.caib.signatura.api.ParsedCertificate;
12  import es.caib.signatura.api.Signature;
13  import es.caib.signatura.api.SignatureDataException;
14  import es.caib.signatura.api.SignatureProviderException;
15  import es.caib.signatura.api.SignatureTimestampException;
16  import es.caib.signatura.api.Signer;
17  import es.caib.signatura.impl.ClassLoaderFactory;
18  import es.caib.signatura.impl.SignatureProviderInterface;
19  
20  /**
21   * Implementación de la interfaz <code>SignatureData</code> para usar con la
22   * entidad certificadora Tradisea
23   * 
24   * @author Jesús Reyes (3dígits)
25   * @version 0.98
26   * @see Signer
27   * @see Signature
28   * 
29   */
30  public class CMSSignature implements Signature, Serializable {
31  
32  	protected byte[] signatureBytes = null; // array de bytes con la firma
33  		
34  	private String contentType = null;
35  
36  	private static final long serialVersionUID = 1;
37  
38  	private transient SignatureProviderInterface impl = null;
39  
40  	/**
41  	 * Crea un nuevo objeto a partir de los atributos de la clase. Es el
42  	 * constructor que debe usar cada implementación de la interfaz
43  	 * <code>Signature</code> para crear una firma. Se extrae el certificado
44  	 * de la firma y se guarda en la propiedad <code>transient</code>
45  	 * certificate para usarla en los métodos que dan información concreta del
46  	 * certificado
47  	 * 
48  	 * @param signatureBytes
49  	 *            array de bytes con la firma digital generada por la api del
50  	 *            proveedor de firma electrónica
51  	 * 
52  	 */
53  	public CMSSignature(byte pkcs7[], String contentType)
54  			throws SignatureDataException {
55  		signatureBytes = pkcs7;
56  		this.contentType = contentType;
57  		try {
58  			init();
59  		} catch (IOException e) {
60  			throw new SignatureDataException(e);
61  		}
62  	}
63  	
64  	public void setContentType(String contentType){		
65  		this.contentType = contentType;
66  	}
67  	
68  	public void setPkcs7(byte pkcs7[]){		
69  		signatureBytes = pkcs7;
70  	}
71  	
72  	public CMSSignature (SignatureProviderInterface impl)
73  	{
74  		this.impl = impl;
75  		signatureBytes = impl.getPkcs7();
76  		contentType = impl.getContentType();
77  	}
78  
79  	private void init() throws IOException {
80  		if (impl == null) {
81  			try {
82  				ClassLoader cl = ClassLoaderFactory.getFactory().getMasterClassLoader();
83  				Class clazz = cl .loadClass( getInternalClassName() );
84  				impl =(SignatureProviderInterface)clazz.newInstance();
85  			} catch (InstantiationException e) {
86  				throw new RuntimeException(e);
87  			} catch (IllegalAccessException e) {
88  				throw new RuntimeException(e);
89  			} catch (ClassNotFoundException e) {
90  				throw new RuntimeException(e);
91  			}
92  		}
93  		try {
94  			impl.setContentType(contentType);
95  			impl.setSignedData(signatureBytes);
96  		} catch (Exception e) {
97  			throw new IOException("Unable to parse signature");
98  		}
99  	}
100 
101 	/**
102 	 * @return
103 	 */
104 	protected String getInternalClassName() {
105 		return "es.caib.signatura.provider.impl.common.CMSSignatureImpl";
106 	}
107 
108 	/**
109 	 * Obtiene el nombre de la entidad certificadora usada en la firma
110 	 * 
111 	 * @return nombre de la entidad certificadora
112 	 */
113 	public String getCertCaName() {
114 		return impl.getCertCaName();
115 	}
116 
117 	/**
118 	 * Obtiene el nombre del certificado usado en la firma
119 	 * 
120 	 * @return nombre del certificado (CommonName)
121 	 */
122 	public String getCertSubjectCommonName() {
123 		return impl.getCertSubjectCommonName();
124 	}
125 
126 	public String getCertSubjectAlternativeNames() {
127 		return impl.getCertSubjectAlternativeNames();
128 	}
129 
130 	public byte[] getPkcs7() {
131 		return this.signatureBytes;
132 	}
133 
134 	// Sobreescribimos el método readObject que deserializa el objeto para
135 	// llamar posteriormente al método privado de inicialización del objetco
136 	// cuyo cometido es extraer el certificado de usuario de la firma
137 	private void readObject(java.io.ObjectInputStream in) throws IOException,
138 			ClassNotFoundException {
139 		in.defaultReadObject();
140 		init();
141 	}
142 
143 	public Date getDate() throws SignatureTimestampException {
144 		return impl.getDate();
145 	}
146 
147 	public boolean verify() throws SignatureVerifyException {
148 		return impl.verify();
149 	}
150 
151 	public String getContentType() {
152 		return contentType;
153 	}
154 
155 	public X509Certificate getCert() {
156 		return impl.getCert();
157 	}
158 
159 	public X509Certificate[] getCertificateChain() throws Exception {
160 		return impl.getCertificateChain();
161 	}
162 
163 	public ParsedCertificate getParsedCertificate() {
164 		return impl.getParsedCertificate();
165 	}
166 
167 	/*
168 	 * (non-Javadoc)
169 	 * 
170 	 * @see es.caib.signatura.api.Signature#verify(java.io.InputStream)
171 	 */
172 
173 	public boolean verify(InputStream contentStream)
174 			throws SignatureProviderException, IOException,
175 			SignatureVerifyException {
176 		boolean isVerified = true;
177 		try{
178 			// verificación interna de la firma
179 			isVerified = isVerified && impl.verify(contentStream);
180 			// isVerified = isVerified && verifyWS();
181 		}catch(SignatureVerifyException e){
182 			throw e;
183 		} catch(Exception e){
184 			throw new SignatureVerifyException(e);
185 		}
186 		return isVerified;
187 	}
188 
189 
190 	public boolean verifyAPosterioriTimestamp(InputStream contentStream) throws SignatureProviderException, IOException,
191 			SignatureVerifyException {
192 		boolean isVerified = true;
193 		try{			
194 			// verificación interna de la firma
195 			isVerified = isVerified && impl.verifyAPosterioriTimestamp(contentStream);
196 			//*
197 			// * Se actualiza la firma por si el validador ha añadido
198 			// * un sello de tiempo
199 
200 			if(isVerified){
201 				this.setPkcs7(impl.getPkcs7());
202 			}
203 
204 		}catch(SignatureVerifyException e){
205 			throw e;
206 		} catch(Exception e){
207 			throw new SignatureVerifyException(e);
208 		}
209 		return isVerified;
210 	}
211 	/*
212 	private boolean WSResponseIsAVerifiedMessage(String result) throws SignatureVerifyException {
213 		String content = new String();
214 		try {
215 			DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
216 			DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
217 			Document document;	    	  
218 			StringBufferInputStream inputStream = new StringBufferInputStream(result);
219 			document = documentBuilder.parse((InputStream)inputStream);	    	  
220 			//Element element = document.getDocumentElement();
221 			try{
222 				NodeList nodeList = document.getElementsByTagName("valido");
223 				Node node = nodeList.item(0);
224 				Element element = (Element) node;
225 				String tagName = element.getTagName();
226 				Node textData = null;
227 				boolean stop = false;
228 				NodeList nodeDataList = element.getChildNodes();				
229 				for(int i = 0;i < nodeDataList.getLength() && !stop;i++){
230 					textData = nodeDataList.item(i);
231 					stop = textData.getNodeType() == org.w3c.dom.Node.TEXT_NODE;						
232 				}
233 				content = ((org.w3c.dom.Text)textData).getData();
234 			}catch(Exception e){
235 				//* Para no llevar a malos entendidos
236 				// * se da la firma como falsa
237 				// *
238 				return false;
239 			}
240 			if(content == null){
241 				throw new Exception("No content in 'valido' TAG. Response message: " + result);
242 			}
243 		}catch(Exception e){
244 			throw new SignatureVerifyException(e);
245 		}
246 		return content.compareToIgnoreCase("true") == 0;
247 	}
248 	 */	
249 }