Update project structure for aaf/cadi
[aaf/cadi.git] / aaf / src / main / java / org / onap / aaf / cadi / aaf / cert / AAFListedCertIdentity.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aaf\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * ===========================================================================\r
7  * * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * * you may not use this file except in compliance with the License.\r
9  * * You may obtain a copy of the License at\r
10  * * \r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * * \r
13  *  * Unless required by applicable law or agreed to in writing, software\r
14  * * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * * See the License for the specific language governing permissions and\r
17  * * limitations under the License.\r
18  * * ============LICENSE_END====================================================\r
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 package org.onap.aaf.cadi.aaf.cert;\r
24 \r
25 \r
26 import java.security.Principal;\r
27 import java.security.cert.CertificateException;\r
28 import java.security.cert.X509Certificate;\r
29 import java.util.HashSet;\r
30 import java.util.List;\r
31 import java.util.Map;\r
32 import java.util.Set;\r
33 import java.util.Timer;\r
34 import java.util.TimerTask;\r
35 import java.util.TreeMap;\r
36 \r
37 import javax.servlet.http.HttpServletRequest;\r
38 import javax.xml.datatype.XMLGregorianCalendar;\r
39 \r
40 import org.onap.aaf.cadi.Access;\r
41 import org.onap.aaf.cadi.Hash;\r
42 import org.onap.aaf.cadi.Access.Level;\r
43 import org.onap.aaf.cadi.aaf.v2_0.AAFCon;\r
44 import org.onap.aaf.cadi.client.Future;\r
45 import org.onap.aaf.cadi.config.Config;\r
46 import org.onap.aaf.cadi.principal.X509Principal;\r
47 import org.onap.aaf.cadi.taf.cert.CertIdentity;\r
48 import org.onap.aaf.cadi.taf.cert.X509Taf;\r
49 \r
50 import org.onap.aaf.inno.env.APIException;\r
51 import org.onap.aaf.inno.env.util.Chrono;\r
52 import org.onap.aaf.inno.env.util.Split;\r
53 \r
54 import aaf.v2_0.Certs;\r
55 import aaf.v2_0.Certs.Cert;\r
56 import aaf.v2_0.Users;\r
57 import aaf.v2_0.Users.User;\r
58 \r
59 public class AAFListedCertIdentity implements CertIdentity {\r
60         //TODO should 8 hours be configurable? \r
61         private static final long EIGHT_HOURS = 1000*60*60*8; \r
62         private static final String AAF_VERSION = "2.0";\r
63                         \r
64         private static Map<ByteArrayHolder,String> certs = null;\r
65         \r
66         // Did this to add other Trust Mechanisms\r
67         // Trust mechanism set by Property: \r
68         private static final String[] authMechanisms = new String[] {"tguard","basicAuth","csp"};\r
69         private static String[] certIDs;\r
70         \r
71         private static Map<String,Set<String>> trusted =null;\r
72 \r
73         public AAFListedCertIdentity(Access access, AAFCon<?> aafcon) throws APIException {\r
74                 synchronized(AAFListedCertIdentity.class) {\r
75                         if(certIDs==null) {\r
76                                 String cip = access.getProperty(Config.AAF_CERT_IDS, null);\r
77                                 if(cip!=null) {\r
78                                         certIDs = Split.split(',',cip);\r
79                                 }\r
80                         }\r
81                         if(certIDs!=null && certs==null) {\r
82                                 TimerTask cu = new CertUpdate(aafcon);\r
83                                 cu.run(); // want this to run in this thread first...\r
84                                 new Timer("AAF Identity Refresh Timer",true).scheduleAtFixedRate(cu, EIGHT_HOURS,EIGHT_HOURS);\r
85                         }\r
86                 }\r
87         }\r
88 \r
89         public static Set<String> trusted(String authMech) {\r
90                 return trusted.get(authMech);\r
91         }\r
92         \r
93         public Principal identity(HttpServletRequest req, X509Certificate cert, byte[] certBytes) throws CertificateException {\r
94                 if(cert==null && certBytes==null)return null;\r
95                 if(certBytes==null)certBytes = cert.getEncoded();\r
96                 byte[] fingerprint = X509Taf.getFingerPrint(certBytes);\r
97                 String id = certs.get(new ByteArrayHolder(fingerprint));\r
98                 if(id!=null) { // Caller is Validated\r
99                         return new X509Principal(id,cert,certBytes);\r
100                 }\r
101                 return null;\r
102         }\r
103 \r
104         private static class ByteArrayHolder implements Comparable<ByteArrayHolder> {\r
105                 private byte[] ba;\r
106                 public ByteArrayHolder(byte[] ba) {\r
107                         this.ba = ba;\r
108                 }\r
109                 public int compareTo(ByteArrayHolder b) {\r
110                         return Hash.compareTo(ba, b.ba);\r
111                 }\r
112         }\r
113         \r
114         private class CertUpdate extends TimerTask {\r
115 \r
116                 private AAFCon<?> aafcon;\r
117                 public CertUpdate(AAFCon<?> con) {\r
118                         aafcon = con;\r
119                 }\r
120                 \r
121                 @Override\r
122                 public void run() {\r
123                         try {\r
124                                 TreeMap<ByteArrayHolder, String> newCertsMap = new TreeMap<ByteArrayHolder,String>();\r
125                                 Map<String,Set<String>> newTrustMap = new TreeMap<String,Set<String>>();\r
126                                 Set<String> userLookup = new HashSet<String>();\r
127                                 for(String s : certIDs) {\r
128                                         userLookup.add(s);\r
129                                 }\r
130                                 for(String authMech : authMechanisms) {\r
131                                         Future<Users> fusr = aafcon.client(AAF_VERSION).read("/authz/users/perm/org.onap.aaf.trust/"+authMech+"/authenticate", Users.class, aafcon.usersDF);\r
132                                         if(fusr.get(5000)) {\r
133                                                 List<User> users = fusr.value.getUser();\r
134                                                 if(users.isEmpty()) {\r
135                                                         aafcon.access.log(Level.WARN, "AAF Lookup-No IDs in Role com.att.aaf.trustForID <> "+authMech);\r
136                                                 } else {\r
137                                                         aafcon.access.log(Level.INFO,"Loading Trust Authentication Info for",authMech);\r
138                                                         Set<String> hsUser = new HashSet<String>();\r
139                                                         for(User u : users) {\r
140                                                                 userLookup.add(u.getId());\r
141                                                                 hsUser.add(u.getId());\r
142                                                         }\r
143                                                         newTrustMap.put(authMech,hsUser);\r
144                                                 }\r
145                                         } else {\r
146                                                 aafcon.access.log(Level.WARN, "Could not get Users in Perm com.att.trust|tguard|authenticate",fusr.code(),fusr.body());\r
147                                         }\r
148                                         \r
149                                 }\r
150                                 \r
151                                 for(String u : userLookup) {\r
152                                         Future<Certs> fc = aafcon.client(AAF_VERSION).read("/authn/cert/id/"+u, Certs.class, aafcon.certsDF);\r
153                                         XMLGregorianCalendar now = Chrono.timeStamp();\r
154                                         if(fc.get(5000)) {\r
155                                                 List<Cert> certs = fc.value.getCert();\r
156                                                 if(certs.isEmpty()) {\r
157                                                         aafcon.access.log(Level.WARN, "No Cert Associations for",u);\r
158                                                 } else {\r
159                                                         for(Cert c : fc.value.getCert()) {\r
160                                                                 XMLGregorianCalendar then =c.getExpires();\r
161                                                                 if(then !=null && then.compare(now)>0) {\r
162                                                                         newCertsMap.put(new ByteArrayHolder(c.getFingerprint()), c.getId());\r
163                                                                         aafcon.access.log(Level.INIT,"Associating "+ c.getId() + " expiring " + Chrono.dateOnlyStamp(c.getExpires()) + " with " + c.getX500());\r
164                                                                 }\r
165                                                         }\r
166                                                 }\r
167                                         } else {\r
168                                                 aafcon.access.log(Level.WARN, "Could not get Certificates for",u);\r
169                                         }\r
170                                 }\r
171 \r
172                                 certs = newCertsMap;\r
173                                 trusted = newTrustMap;\r
174                         } catch(Exception e) {\r
175                                 aafcon.access.log(e, "Failure to update Certificate Identities from AAF");\r
176                         }\r
177                 }\r
178         }\r
179 }\r