1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package edu.internet2.middleware.shibboleth.common.config.security;
19
20 import java.security.cert.CRLException;
21 import java.security.cert.CertificateException;
22 import java.security.cert.X509CRL;
23 import java.security.cert.X509Certificate;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.List;
27 import java.util.Map;
28
29 import javax.xml.namespace.QName;
30
31 import org.opensaml.xml.security.x509.X509Util;
32 import org.opensaml.xml.util.DatatypeHelper;
33 import org.opensaml.xml.util.XMLHelper;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36 import org.springframework.beans.FatalBeanException;
37 import org.springframework.beans.factory.support.AbstractBeanDefinition;
38 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
39 import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
40 import org.springframework.beans.factory.xml.ParserContext;
41 import org.w3c.dom.Element;
42
43
44
45
46 public abstract class AbstractPKIXValidationInformationBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
47
48
49 private final Logger log = LoggerFactory.getLogger(AbstractX509CredentialBeanDefinitionParser.class);
50
51
52 protected Class getBeanClass(Element element) {
53 return PKIXValidationInformationFactoryBean.class;
54 }
55
56
57 protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) {
58 return element.getAttributeNS(null, "id");
59 }
60
61
62 protected void doParse(Element element, BeanDefinitionBuilder builder) {
63 log.debug("Parsing PKIX ValidationInfo: {}", element.getAttributeNS(null, "id"));
64
65 int depth = 1;
66 if (element.hasAttributeNS(null, "verifyDepth")) {
67 depth = new Integer(DatatypeHelper.safeTrim(element.getAttributeNS(null, "verifyDepth")));
68 }
69
70 builder.addPropertyValue("verifyDepth", depth);
71
72 Map<QName, List<Element>> configChildren = XMLHelper.getChildElements(element);
73
74 parseCertificates(configChildren, builder);
75 parseCRLs(configChildren, builder);
76 }
77
78
79
80
81
82
83
84 protected void parseCertificates(Map<QName, List<Element>> configChildren, BeanDefinitionBuilder builder) {
85 List<Element> certElems = configChildren.get(new QName(SecurityNamespaceHandler.NAMESPACE, "Certificate"));
86 if (certElems == null || certElems.isEmpty()) {
87 return;
88 }
89
90 log.debug("Parsing PKIX validation info certificates");
91 ArrayList<X509Certificate> certs = new ArrayList<X509Certificate>();
92 byte[] encodedCert;
93 Collection<X509Certificate> decodedCerts;
94 for (Element certElem : certElems) {
95 encodedCert = getEncodedCertificate(DatatypeHelper.safeTrimOrNullString(certElem.getTextContent()));
96 if (encodedCert == null) {
97 continue;
98 }
99
100 try {
101 decodedCerts = X509Util.decodeCertificate(encodedCert);
102 certs.addAll(decodedCerts);
103 } catch (CertificateException e) {
104 throw new FatalBeanException("Unable to create PKIX validation info, unable to parse certificates", e);
105 }
106 }
107
108 builder.addPropertyValue("certificates", certs);
109 }
110
111
112
113
114
115
116
117
118 protected abstract byte[] getEncodedCertificate(String certConfigContent);
119
120
121
122
123
124
125
126 protected void parseCRLs(Map<QName, List<Element>> configChildren, BeanDefinitionBuilder builder) {
127 List<Element> crlElems = configChildren.get(new QName(SecurityNamespaceHandler.NAMESPACE, "CRL"));
128 if (crlElems == null || crlElems.isEmpty()) {
129 return;
130 }
131
132 log.debug("Parsing PKIX validation info CRLs");
133 ArrayList<X509CRL> crls = new ArrayList<X509CRL>();
134 byte[] encodedCRL;
135 Collection<X509CRL> decodedCRLs;
136 for (Element crlElem : crlElems) {
137 encodedCRL = getEncodedCRL(DatatypeHelper.safeTrimOrNullString(crlElem.getTextContent()));
138 if (encodedCRL == null) {
139 continue;
140 }
141
142 try {
143 decodedCRLs = X509Util.decodeCRLs(encodedCRL);
144 crls.addAll(decodedCRLs);
145 } catch (CRLException e) {
146 throw new FatalBeanException("Unable to create PKIX validation info, unable to parse CRLs", e);
147 }
148 }
149
150 builder.addPropertyValue("crls", crls);
151 }
152
153
154
155
156
157
158
159
160 protected abstract byte[] getEncodedCRL(String certCRLContent);
161 }