1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.rice.ksb.security;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.IOException;
21 import java.security.Signature;
22 import java.security.cert.CertificateFactory;
23
24 import javax.servlet.ServletInputStream;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletRequestWrapper;
27
28 import org.apache.commons.codec.binary.Base64;
29 import org.apache.commons.lang.StringUtils;
30 import org.kuali.rice.ksb.service.KSBServiceLocator;
31 import org.kuali.rice.ksb.util.KSBConstants;
32
33
34
35
36
37
38
39
40 public class SignatureVerifyingRequestWrapper extends HttpServletRequestWrapper {
41
42 private byte[] digitalSignature;
43 private Signature signature;
44
45 public SignatureVerifyingRequestWrapper(HttpServletRequest request) {
46 super(request);
47 String encodedSignature = request.getHeader(KSBConstants.DIGITAL_SIGNATURE_HEADER);
48 if (StringUtils.isEmpty(encodedSignature)) {
49 throw new RuntimeException("A digital signature was required on the request but none was found.");
50 }
51 String verificationAlias = request.getHeader(KSBConstants.KEYSTORE_ALIAS_HEADER);
52 String encodedCertificate = request.getHeader(KSBConstants.KEYSTORE_CERTIFICATE_HEADER);
53 if ( (StringUtils.isEmpty(verificationAlias)) && (StringUtils.isEmpty(encodedCertificate)) ) {
54 throw new RuntimeException("A verification alias or certificate was required on the request but neither was found.");
55 }
56 try {
57 this.digitalSignature = Base64.decodeBase64(encodedSignature.getBytes("UTF-8"));
58 if (StringUtils.isNotBlank(encodedCertificate)) {
59 byte[] certificate = Base64.decodeBase64(encodedCertificate.getBytes("UTF-8"));
60 CertificateFactory cf = CertificateFactory.getInstance("X.509");
61 this.signature = KSBServiceLocator.getDigitalSignatureService().getSignatureForVerification(cf.generateCertificate(new ByteArrayInputStream(certificate)));
62 } else if (StringUtils.isNotBlank(verificationAlias)) {
63 this.signature = KSBServiceLocator.getDigitalSignatureService().getSignatureForVerification(verificationAlias);
64 }
65 } catch (Exception e) {
66 throw new RuntimeException("Failed to initialize digital signature verification.", e);
67 }
68 }
69
70 @Override
71 public ServletInputStream getInputStream() throws IOException {
72 return new SignatureVerifyingInputStream(this.digitalSignature, this.signature, super.getInputStream());
73 }
74
75 }