+++ /dev/null
-/*******************************************************************************\r
- * ============LICENSE_START====================================================\r
- * * org.onap.aaf\r
- * * ===========================================================================\r
- * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
- * * ===========================================================================\r
- * * Licensed under the Apache License, Version 2.0 (the "License");\r
- * * you may not use this file except in compliance with the License.\r
- * * You may obtain a copy of the License at\r
- * * \r
- * * http://www.apache.org/licenses/LICENSE-2.0\r
- * * \r
- * * Unless required by applicable law or agreed to in writing, software\r
- * * distributed under the License is distributed on an "AS IS" BASIS,\r
- * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * * See the License for the specific language governing permissions and\r
- * * limitations under the License.\r
- * * ============LICENSE_END====================================================\r
- * *\r
- * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
- * *\r
- ******************************************************************************/\r
-package org.onap.aaf.cadi.taf.cert;\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.IOException;\r
-import java.security.GeneralSecurityException;\r
-import java.security.MessageDigest;\r
-import java.security.NoSuchAlgorithmException;\r
-import java.security.Principal;\r
-import java.security.Signature;\r
-import java.security.cert.CertificateException;\r
-import java.security.cert.CertificateFactory;\r
-import java.security.cert.X509Certificate;\r
-import java.util.ArrayList;\r
-\r
-import javax.net.ssl.TrustManagerFactory;\r
-import javax.servlet.http.HttpServletRequest;\r
-import javax.servlet.http.HttpServletResponse;\r
-\r
-import org.onap.aaf.cadi.Access;\r
-import org.onap.aaf.cadi.CachedPrincipal;\r
-import org.onap.aaf.cadi.CadiException;\r
-import org.onap.aaf.cadi.Lur;\r
-import org.onap.aaf.cadi.Symm;\r
-import org.onap.aaf.cadi.Access.Level;\r
-import org.onap.aaf.cadi.CachedPrincipal.Resp;\r
-import org.onap.aaf.cadi.Taf.LifeForm;\r
-import org.onap.aaf.cadi.config.Config;\r
-import org.onap.aaf.cadi.config.SecurityInfo;\r
-import org.onap.aaf.cadi.config.SecurityInfoC;\r
-import org.onap.aaf.cadi.lur.LocalPermission;\r
-import org.onap.aaf.cadi.principal.TGuardPrincipal;\r
-import org.onap.aaf.cadi.principal.X509Principal;\r
-import org.onap.aaf.cadi.taf.HttpTaf;\r
-import org.onap.aaf.cadi.taf.TafResp;\r
-import org.onap.aaf.cadi.taf.TafResp.RESP;\r
-import org.onap.aaf.cadi.util.Split;\r
-\r
-public class X509Taf implements HttpTaf {\r
- \r
- public static final CertificateFactory certFactory;\r
- public static final MessageDigest messageDigest;\r
- public static final TrustManagerFactory tmf;\r
- private Access access;\r
- private CertIdentity[] certIdents;\r
- private Lur lur;\r
- private ArrayList<String> cadiIssuers;\r
- private String env;\r
- private SecurityInfo si;\r
-\r
- static {\r
- try {\r
- certFactory = CertificateFactory.getInstance("X.509");\r
- messageDigest = MessageDigest.getInstance("SHA-256"); // use this to clone\r
- tmf = TrustManagerFactory.getInstance(SecurityInfoC.SslKeyManagerFactoryAlgorithm);\r
- } catch (Exception e) {\r
- throw new RuntimeException("X.509 and SHA-256 are required for X509Taf",e);\r
- }\r
- }\r
- \r
- public X509Taf(Access access, Lur lur, CertIdentity ... cis) throws CertificateException, NoSuchAlgorithmException, CadiException {\r
- this.access = access;\r
- env = access.getProperty(Config.AAF_ENV,null);\r
- if(env==null) {\r
- throw new CadiException("X509Taf requires Environment ("+Config.AAF_ENV+") to be set.");\r
- }\r
- this.lur = lur;\r
- this.cadiIssuers = new ArrayList<String>();\r
- for(String ci : access.getProperty(Config.CADI_X509_ISSUERS, "CN=ATT CADI Issuing CA 01, OU=CSO, O=ATT, C=US:CN=ATT CADI Issuing CA 02, OU=CSO, O=ATT, C=US").split(":")) {\r
- cadiIssuers.add(ci);\r
- }\r
- try {\r
- Class<?> dci = access.classLoader().loadClass("com.att.authz.cadi.DirectCertIdentity");\r
- CertIdentity temp[] = new CertIdentity[cis.length+1];\r
- System.arraycopy(cis, 0, temp, 1, cis.length);\r
- temp[0] = (CertIdentity) dci.newInstance();\r
- certIdents=temp;\r
- } catch (Exception e) {\r
- certIdents = cis;\r
- }\r
- \r
- try {\r
- si = new SecurityInfo(access);\r
- } catch (GeneralSecurityException | IOException e1) {\r
- throw new CadiException(e1);\r
- }\r
- }\r
-\r
- public static final X509Certificate getCert(byte[] certBytes) throws CertificateException {\r
- ByteArrayInputStream bais = new ByteArrayInputStream(certBytes);\r
- return (X509Certificate)certFactory.generateCertificate(bais);\r
- }\r
-\r
- public static final byte[] getFingerPrint(byte[] ba) {\r
- MessageDigest md;\r
- try {\r
- md = (MessageDigest)messageDigest.clone();\r
- } catch (CloneNotSupportedException e) {\r
- // should never get here\r
- return new byte[0];\r
- }\r
- md.update(ba);\r
- return md.digest();\r
- }\r
-\r
- public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp) {\r
- // Check for Mutual SSL\r
- try {\r
- X509Certificate[] certarr = (X509Certificate[])req.getAttribute("javax.servlet.request.X509Certificate");\r
- if(certarr!=null && certarr.length>0) {\r
- si.checkClientTrusted(certarr);\r
- // Note: If the Issuer is not in the TrustStore, it's not added to the Cert list\r
- if(cadiIssuers.contains(certarr[0].getIssuerDN().toString())) {\r
- String x500 = certarr[0].getSubjectDN().getName();\r
- int ou=x500.indexOf("OU=");\r
- if(ou>0) {\r
- ou+=3;\r
- int comma = x500.indexOf(',',ou);\r
- if(comma>0) {\r
- String id= x500.substring(ou,comma);\r
- String idenv[] = id.split(":");\r
- if(idenv.length==1 || (idenv.length>1 && env.equals(idenv[1]))) {\r
- return new X509HttpTafResp(access, \r
- new X509Principal(idenv[0], certarr[0],null), \r
- id + " validated by CADI x509", RESP.IS_AUTHENTICATED);\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- byte[] array = null;\r
- byte[] certBytes = null;\r
- X509Certificate cert=null;\r
- String responseText=null;\r
- String authHeader = req.getHeader("Authorization");\r
-\r
- if(certarr!=null) { // If cert !=null, Cert is Tested by Mutual Protocol.\r
- if(authHeader!=null) { // This is only intended to be a Secure Connection, not an Identity\r
- return new X509HttpTafResp(access, null, "Certificate verified, but another Identity is presented", RESP.TRY_ANOTHER_TAF);\r
- }\r
- cert = certarr[0];\r
- responseText = ", validated by Mutual SSL Protocol";\r
- } else { // If cert == null, Get Declared Cert (in header), but validate by having them sign something\r
- if(authHeader != null && authHeader.startsWith("x509 ")) {\r
- ByteArrayOutputStream baos = new ByteArrayOutputStream(authHeader.length());\r
- try {\r
- array = authHeader.getBytes();\r
- ByteArrayInputStream bais = new ByteArrayInputStream(array);\r
- Symm.base64noSplit.decode(bais, baos, 5);\r
- certBytes = baos.toByteArray();\r
- cert = getCert(certBytes);\r
- \r
- /** \r
- * Identity from CERT if well know CA and specific encoded information\r
- */\r
- // If found Identity doesn't work, try SignedStuff Protocol\r
-// cert.checkValidity();\r
-// cert.--- GET FINGERPRINT?\r
- String stuff = req.getHeader("Signature");\r
- if(stuff==null) \r
- return new X509HttpTafResp(access, null, "Header entry 'Signature' required to validate One way X509 Certificate", RESP.TRY_ANOTHER_TAF);\r
- String data = req.getHeader("Data"); \r
-// if(data==null) \r
-// return new X509HttpTafResp(access, null, "No signed Data to validate with X509 Certificate", RESP.TRY_ANOTHER_TAF);\r
-\r
- // Note: Data Pos shows is "<signatureType> <data>"\r
-// int dataPos = (stuff.indexOf(' ')); // determine what is Algorithm\r
- // Get Signature \r
- bais = new ByteArrayInputStream(stuff.getBytes());\r
- baos = new ByteArrayOutputStream(stuff.length());\r
- Symm.base64noSplit.decode(bais, baos);\r
- array = baos.toByteArray();\r
-// Signature sig = Signature.getInstance(stuff.substring(0, dataPos)); // get Algorithm from first part of Signature\r
- \r
- Signature sig = Signature.getInstance(cert.getSigAlgName()); \r
- sig.initVerify(cert.getPublicKey());\r
- sig.update(data.getBytes());\r
- if(!sig.verify(array)) {\r
- access.log(Level.ERROR, "Signature doesn't Match");\r
- return new X509HttpTafResp(access, null, "Certificate NOT verified", RESP.TRY_ANOTHER_TAF);\r
- }\r
- responseText = ", validated by Signed Data";\r
- } catch (Exception e) {\r
- access.log(e, "Exception while validating Cert");\r
- return new X509HttpTafResp(access, null, "Certificate NOT verified", RESP.TRY_ANOTHER_TAF);\r
- }\r
- \r
- } else {\r
- return new X509HttpTafResp(access, null, "No Certificate Info on Transaction", RESP.TRY_ANOTHER_TAF);\r
- }\r
- }\r
-\r
- // A cert has been found, match Identify\r
- Principal prin=null;\r
- \r
- for(int i=0;prin==null && i<certIdents.length;++i) {\r
- if((prin=certIdents[i].identity(req, cert, certBytes))!=null) {\r
- responseText = prin.getName() + " matches Certificate " + cert.getSubjectX500Principal().getName() + responseText;\r
-// xresp = new X509HttpTafResp(\r
-// access,\r
-// prin,\r
-// prin.getName() + " matches Certificate " + cert.getSubjectX500Principal().getName() + responseText,\r
-// RESP.IS_AUTHENTICATED);\r
- \r
- }\r
- }\r
-\r
- // if Principal is found, check for "AS_USER" and whether this entity is trusted to declare\r
- if(prin!=null) {\r
- String as_user=req.getHeader(Config.CADI_USER_CHAIN);\r
- if(as_user!=null) {\r
- if(as_user.startsWith("TGUARD ") && lur.fish(prin, new LocalPermission("com.att.aaf.trust|"+prin.getName()+"|tguard"))) {\r
- prin = new TGuardPrincipal(as_user.substring(7));\r
- responseText=prin.getName() + " set via trust of " + responseText;\r
- }\r
- }\r
- return new X509HttpTafResp(\r
- access,\r
- prin,\r
- responseText,\r
- RESP.IS_AUTHENTICATED);\r
- }\r
- } catch(Exception e) {\r
- return new X509HttpTafResp(access, null, e.getMessage(), RESP.TRY_ANOTHER_TAF); \r
- }\r
- \r
- return new X509HttpTafResp(access, null, "Certificate NOT verified", RESP.TRY_ANOTHER_TAF);\r
- }\r
-\r
- public Resp revalidate(CachedPrincipal prin) {\r
- return null;\r
- }\r
-\r
-}\r