Merge "[AAI] Fix doc config files"
[aai/aai-common.git] / aai-aaf-auth / src / main / java / org / onap / aai / aaf / auth / CertUtil.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *    http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.aai.aaf.auth;
22
23 import java.io.FileInputStream;
24 import java.io.IOException;
25 import java.security.cert.X509Certificate;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Collections;
29 import java.util.List;
30 import java.util.Objects;
31 import java.util.Properties;
32 import java.util.stream.Collectors;
33
34 import javax.servlet.http.HttpServletRequest;
35
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * The Class CertUtil provides cert related utility methods.
41  */
42 public class CertUtil {
43     public static final String DEFAULT_CADI_ISSUERS = "CN=ATT AAF CADI Test Issuing "
44             + "CA 01, OU=CSO, O=ATT, C=US:CN=ATT AAF CADI Test Issuing CA 02, OU=CSO, O=ATT, C=US";
45     public static final String CADI_PROP_FILES = "cadi_prop_files";
46     public static final String CADI_ISSUERS_PROP_NAME = "cadi_x509_issuers";
47     public static final String CADI_ISSUERS_SEPARATOR = ":";
48     public static final String AAI_SSL_CLIENT_OU_HDR = "X-AAI-SSL-Client-OU";
49     public static final String AAI_SSL_ISSUER_HDR = "X-AAI-SSL-Issuer";
50     public static final String AAI_SSL_CLIENT_CN_HDR = "X-AAI-SSL-Client-CN";
51     public static final String AAI_SSL_CLIENT_O_HDR = "X-AAI-SSL-Client-O";
52     public static final String AAI_SSL_CLIENT_L_HDR = "X-AAI-SSL-Client-L";
53     public static final String AAI_SSL_CLIENT_ST_HDR = "X-AAI-SSL-Client-ST";
54     public static final String AAI_SSL_CLIENT_C_HDR = "X-AAI-SSL-Client-C";
55     public static final String AAF_USER_CHAIN_HDR = "USER_CHAIN";
56     public static final String AAF_ID = "<AAF-ID>";
57     private static final Logger LOGGER = LoggerFactory.getLogger(CertUtil.class);
58
59     public static String getAaiSslClientOuHeader(HttpServletRequest hsr) {
60         return (hsr.getHeader(AAI_SSL_CLIENT_OU_HDR));
61     }
62
63     public static boolean isHaProxy(HttpServletRequest hsr) {
64
65         String haProxyUser = "";
66         if (Objects.isNull(hsr.getHeader(AAI_SSL_CLIENT_CN_HDR)) || Objects.isNull(hsr.getHeader(AAI_SSL_CLIENT_OU_HDR))
67                 || Objects.isNull(hsr.getHeader(AAI_SSL_CLIENT_O_HDR))
68                 || Objects.isNull(hsr.getHeader(AAI_SSL_CLIENT_L_HDR))
69                 || Objects.isNull(hsr.getHeader(AAI_SSL_CLIENT_ST_HDR))
70                 || Objects.isNull(hsr.getHeader(AAI_SSL_CLIENT_C_HDR))) {
71             haProxyUser = "";
72         } else {
73             haProxyUser = String.format("CN=%s, OU=%s, O=\"%s\", L=%s, ST=%s, C=%s",
74                     Objects.toString(hsr.getHeader(AAI_SSL_CLIENT_CN_HDR), ""),
75                     Objects.toString(hsr.getHeader(AAI_SSL_CLIENT_OU_HDR), ""),
76                     Objects.toString(hsr.getHeader(AAI_SSL_CLIENT_O_HDR), ""),
77                     Objects.toString(hsr.getHeader(AAI_SSL_CLIENT_L_HDR), ""),
78                     Objects.toString(hsr.getHeader(AAI_SSL_CLIENT_ST_HDR), ""),
79                     Objects.toString(hsr.getHeader(AAI_SSL_CLIENT_C_HDR), "")).toLowerCase();
80         }
81         if (!haProxyUser.isEmpty()) {
82             LOGGER.debug("isHaProxy haProxyUser=" + haProxyUser);
83             return true;
84         }
85         LOGGER.debug("isHaProxy haProxyUser not found");
86         return false;
87     }
88
89     public static String getMechId(HttpServletRequest hsr) {
90         String mechId = null;
91         String ou = getAaiSslClientOuHeader(hsr);
92         if ((ou != null) && (!ou.isEmpty())) {
93             String[] parts = ou.split(CADI_ISSUERS_SEPARATOR);
94             if (parts != null && parts.length >= 1) {
95                 mechId = parts[0];
96             }
97         }
98         LOGGER.debug("getMechId mechId=" + mechId);
99         return (mechId);
100     }
101
102     public static String getCertIssuer(HttpServletRequest hsr) {
103         String issuer = hsr.getHeader(AAI_SSL_ISSUER_HDR);
104         if (issuer != null && !issuer.isEmpty()) {
105             LOGGER.debug("getCertIssuer issuer from header " + AAI_SSL_ISSUER_HDR + " " + issuer);
106             // the haproxy header replaces the ', ' with '/' and reverses on the '/' need to undo that.
107             List<String> broken = Arrays.asList(issuer.split("/"));
108             broken = broken.stream().filter(s -> !s.isEmpty()).collect(Collectors.toList());
109             Collections.reverse(broken);
110             issuer = String.join(", ", broken);
111         } else {
112             if (hsr.getAttribute("javax.servlet.request.cipher_suite") != null) {
113                 X509Certificate[] certChain =
114                         (X509Certificate[]) hsr.getAttribute("javax.servlet.request.X509Certificate");
115                 if (certChain != null && certChain.length > 0) {
116                     X509Certificate clientCert = certChain[0];
117                     issuer = clientCert.getIssuerX500Principal().getName();
118                     LOGGER.debug("getCertIssuer issuer from client cert " + issuer);
119                 }
120             }
121         }
122         return issuer;
123     }
124
125     public static List<String> getCadiCertIssuers(Properties cadiProperties) {
126
127         List<String> defaultList = new ArrayList<>();
128         List<String> resultList = new ArrayList<String>();
129
130         String[] cadiIssuers = DEFAULT_CADI_ISSUERS.split(CADI_ISSUERS_SEPARATOR);
131         for (String issuer : cadiIssuers) {
132             defaultList.add(issuer.replaceAll("\\s+", "").toUpperCase());
133         }
134         try {
135             String certPropFileName = cadiProperties.getProperty(CADI_PROP_FILES);
136             String configuredIssuers = DEFAULT_CADI_ISSUERS;
137             Properties certProperties = new Properties();
138             if (certPropFileName != null) {
139                 try (FileInputStream fis = new FileInputStream(certPropFileName)) {
140                     certProperties.load(fis);
141                 }
142                 configuredIssuers = certProperties.getProperty(CADI_ISSUERS_PROP_NAME);
143             }
144             if ((configuredIssuers != null) && (!configuredIssuers.isEmpty())) {
145                 cadiIssuers = configuredIssuers.split(CADI_ISSUERS_SEPARATOR);
146                 for (String issuer : cadiIssuers) {
147                     resultList.add(issuer.replaceAll("\\s+", "").toUpperCase());
148                 }
149             }
150         } catch (IOException ioe) {
151             return (defaultList);
152         }
153         if (resultList.isEmpty()) {
154             return defaultList;
155         }
156         LOGGER.debug("getCadiCertIssuers " + resultList.toString());
157         return resultList;
158     }
159
160     public static String buildUserChainHeader(String user, String userChainPattern) {
161         // aaf.userchain.pattern=<AAF-ID>:${aaf.userchain.service.reference}:${aaf.userchain.auth.type}:AS
162         return (userChainPattern.replaceAll(AAF_ID, user));
163     }
164 }