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