1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\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
11 * * http://www.apache.org/licenses/LICENSE-2.0
\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
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
22 ******************************************************************************/
\r
23 package org.onap.aaf.cadi.aaf.cert;
\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
37 import javax.servlet.http.HttpServletRequest;
\r
38 import javax.xml.datatype.XMLGregorianCalendar;
\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
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
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
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
64 private static Map<ByteArrayHolder,String> certs = null;
\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
71 private static Map<String,Set<String>> trusted =null;
\r
73 public AAFListedCertIdentity(Access access, AAFCon<?> aafcon) throws APIException {
\r
74 synchronized(AAFListedCertIdentity.class) {
\r
76 String cip = access.getProperty(Config.AAF_CERT_IDS, null);
\r
78 certIDs = Split.split(',',cip);
\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
89 public static Set<String> trusted(String authMech) {
\r
90 return trusted.get(authMech);
\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
104 private static class ByteArrayHolder implements Comparable<ByteArrayHolder> {
\r
106 public ByteArrayHolder(byte[] ba) {
\r
109 public int compareTo(ByteArrayHolder b) {
\r
110 return Hash.compareTo(ba, b.ba);
\r
114 private class CertUpdate extends TimerTask {
\r
116 private AAFCon<?> aafcon;
\r
117 public CertUpdate(AAFCon<?> con) {
\r
122 public void run() {
\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
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
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
143 newTrustMap.put(authMech,hsUser);
\r
146 aafcon.access.log(Level.WARN, "Could not get Users in Perm com.att.trust|tguard|authenticate",fusr.code(),fusr.body());
\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
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
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
168 aafcon.access.log(Level.WARN, "Could not get Certificates for",u);
\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