* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
throw new RuntimeException("X.509 and SHA-256 are required for X509Taf",e);
}
}
-
+
public X509Taf(Access access, Lur lur, CertIdentity ... cis) throws CertificateException, NoSuchAlgorithmException, CadiException {
this.access = access;
env = access.getProperty(Config.AAF_ENV,null);
- if(env==null) {
+ if (env==null) {
throw new CadiException("X509Taf requires Environment ("+Config.AAF_ENV+") to be set.");
}
// this.lur = lur;
this.cadiIssuers = new ArrayList<>();
- for(String ci : access.getProperty(Config.CADI_X509_ISSUERS, "").split(":")) {
+ for (String ci : access.getProperty(Config.CADI_X509_ISSUERS, "").split(":")) {
access.printf(Level.INIT, "Trusting Identity for Certificates signed by \"%s\"",ci);
cadiIssuers.add(ci);
}
try {
Class<?> dci = access.classLoader().loadClass("org.onap.aaf.auth.direct.DirectCertIdentity");
- if(dci==null) {
+ if (dci==null) {
certIdents = cis;
} else {
CertIdentity temp[] = new CertIdentity[cis.length+1];
} catch (Exception e) {
certIdents = cis;
}
-
+
si = new SecurityInfo(access);
}
// Check for Mutual SSL
try {
X509Certificate[] certarr = (X509Certificate[])req.getAttribute("javax.servlet.request.X509Certificate");
- if(certarr!=null && certarr.length>0) {
+ if (certarr!=null && certarr.length>0) {
si.checkClientTrusted(certarr);
// Note: If the Issuer is not in the TrustStore, it's not added to the Cert list
String issuer = certarr[0].getIssuerDN().toString();
- if(cadiIssuers.contains(issuer)) {
- String subject = certarr[0].getSubjectDN().getName();
+ String subject = certarr[0].getSubjectDN().getName();
+ access.printf(Level.DEBUG,"Client Certificate found\n Subject '%s'\n Issuer '%s'",subject,issuer);
+ if (cadiIssuers.contains(issuer)) {
// avoiding extra object creation, since this is validated EVERY transaction with a Cert
- int at = subject.indexOf('@');
- if(at>=0) {
- int start = subject.lastIndexOf(',', at);
- if(start<0) {
- start = 0;
+ int start = 0;
+ int end = 1;
+ int comma;
+ int length = subject.length();
+
+ compare:
+ while(start<length) {
+ while(Character.isWhitespace(subject.charAt(start))) {
+ if(++start>length) {
+ break compare;
+ }
}
- int end = subject.indexOf(',', at);
- if(end<0) {
- end=subject.length();
+ comma = subject.indexOf(',',start);
+ if(comma<0) {
+ end = subject.length();
+ } else {
+ end = comma<=0?0:comma-1;
}
- int temp;
- if(((temp=subject.indexOf("OU=",start))>=0 && temp<end) ||
- ((temp=subject.indexOf("CN=",start))>=0 && temp<end)) {
- String[] sa = Split.splitTrim(':', subject, temp+3,end);
- if(sa.length==1 || (sa.length>1 && env!=null && env.equals(sa[1]))) { // Check Environment
- return new X509HttpTafResp(access,
- new X509Principal(sa[0], certarr[0],(byte[])null,bht),
- "X509Taf validated " + sa[0] + (sa.length<2?"":" for aaf_env " + env ), RESP.IS_AUTHENTICATED);
+ while(Character.isWhitespace(subject.charAt(end))) {
+ if(--end < 0) {
+ break compare;
}
}
-
+ if(subject.regionMatches(start, "OU=", 0, 3) ||
+ subject.regionMatches(start, "CN=", 0, 3)) {
+ int at = subject.indexOf('@', start);
+ if(at<end && at>=0) {
+ String[] sa = Split.splitTrim(':', subject, start+3,end+1);
+ if (sa.length==1 || (sa.length>1 && env!=null && env.equals(sa[1]))) { // Check Environment
+ return new X509HttpTafResp(access,
+ new X509Principal(sa[0], certarr[0],(byte[])null,bht),
+ "X509Taf validated " + sa[0] + (sa.length<2?"":" for aaf_env " + env ), RESP.IS_AUTHENTICATED);
+ } else {
+ access.printf(Level.DEBUG,"Certificate is not for environment '%s'",env);
+ break;
+ }
+ }
+ }
+ start = comma+1;
}
+ access.log(Level.DEBUG,"Certificate is not acceptable for Authentication");
+ } else {
+ access.log(Level.DEBUG,"Issuer is not trusted for Authentication");
}
+ } else {
+ access.log(Level.DEBUG,"There is no client certificate on the transaction");
}
-
+
byte[] array = null;
byte[] certBytes = null;
String responseText=null;
String authHeader = req.getHeader("Authorization");
- if(certarr!=null) { // If cert !=null, Cert is Tested by Mutual Protocol.
- if(authHeader!=null) { // This is only intended to be a Secure Connection, not an Identity
- for(String auth : Split.split(',',authHeader)) {
- if(auth.startsWith("Bearer ")) { // Bearer = OAuth... Don't use as Authenication
+ if (certarr!=null) { // If cert !=null, Cert is Tested by Mutual Protocol.
+ if (authHeader!=null) { // This is only intended to be a Secure Connection, not an Identity
+ for (String auth : Split.split(',',authHeader)) {
+ if (auth.startsWith("Bearer ")) { // Bearer = OAuth... Don't use as Authenication
return new X509HttpTafResp(access, null, "Certificate verified, but Bearer Token is presented", RESP.TRY_ANOTHER_TAF);
}
}
cert = certarr[0];
responseText = ", validated by Mutual SSL Protocol";
} else { // If cert == null, Get Declared Cert (in header), but validate by having them sign something
- if(authHeader != null) {
- for(String auth : Split.splitTrim(',',authHeader)) {
- if(auth.startsWith("x509 ")) {
+ if (authHeader != null) {
+ for (String auth : Split.splitTrim(',',authHeader)) {
+ if (auth.startsWith("x509 ")) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(auth.length());
try {
array = auth.getBytes();
Symm.base64noSplit.decode(bais, baos, 5);
certBytes = baos.toByteArray();
cert = getCert(certBytes);
-
- /**
+
+ /**
* Identity from CERT if well know CA and specific encoded information
*/
// If found Identity doesn't work, try SignedStuff Protocol
// cert.checkValidity();
// cert.--- GET FINGERPRINT?
String stuff = req.getHeader("Signature");
- if(stuff==null)
+ if (stuff==null)
return new X509HttpTafResp(access, null, "Header entry 'Signature' required to validate One way X509 Certificate", RESP.TRY_ANOTHER_TAF);
- String data = req.getHeader("Data");
- // if(data==null)
+ String data = req.getHeader("Data");
+ // if (data==null)
// return new X509HttpTafResp(access, null, "No signed Data to validate with X509 Certificate", RESP.TRY_ANOTHER_TAF);
-
+
// Note: Data Pos shows is "<signatureType> <data>"
// int dataPos = (stuff.indexOf(' ')); // determine what is Algorithm
- // Get Signature
+ // Get Signature
bais = new ByteArrayInputStream(stuff.getBytes());
baos = new ByteArrayOutputStream(stuff.length());
Symm.base64noSplit.decode(bais, baos);
array = baos.toByteArray();
// Signature sig = Signature.getInstance(stuff.substring(0, dataPos)); // get Algorithm from first part of Signature
-
- Signature sig = Signature.getInstance(cert.getSigAlgName());
+
+ Signature sig = Signature.getInstance(cert.getSigAlgName());
sig.initVerify(cert.getPublicKey());
sig.update(data.getBytes());
- if(!sig.verify(array)) {
+ if (!sig.verify(array)) {
access.log(Level.ERROR, "Signature doesn't Match");
return new X509HttpTafResp(access, null, CERTIFICATE_NOT_VALID_FOR_AUTHENTICATION, RESP.TRY_ANOTHER_TAF);
}
}
}
}
- if(cert==null) {
+ if (cert==null) {
return new X509HttpTafResp(access, null, "No Certificate Info on Transaction", RESP.TRY_ANOTHER_TAF);
}
-
+
// A cert has been found, match Identify
TaggedPrincipal prin=null;
-
- for(int i=0;prin==null && i<certIdents.length;++i) {
- if((prin=certIdents[i].identity(req, cert, certBytes))!=null) {
+
+ for (int i=0;prin==null && i<certIdents.length;++i) {
+ if ((prin=certIdents[i].identity(req, cert, certBytes))!=null) {
responseText = prin.getName() + " matches Certificate " + cert.getSubjectX500Principal().getName() + responseText;
}
}
-
+
// if Principal is found, check for "AS_USER" and whether this entity is trusted to declare
- if(prin!=null) {
+ if (prin!=null) {
+ // Note: Tag for Certs is Fingerprint, but that takes computation... leaving off
return new X509HttpTafResp(
access,
prin,
RESP.IS_AUTHENTICATED);
}
}
- } catch(Exception e) {
- return new X509HttpTafResp(access, null, e.getMessage(), RESP.TRY_ANOTHER_TAF);
+ } catch (Exception e) {
+ return new X509HttpTafResp(access, null, e.getMessage(), RESP.TRY_ANOTHER_TAF);
}
-
+
return new X509HttpTafResp(access, null, "Certificate cannot be used for authentication", RESP.TRY_ANOTHER_TAF);
}
public void add(BasicHttpTaf bht) {
this.bht = bht;
}
-
+
public CredVal getCredVal(final String key) {
- if(bht==null) {
+ if (bht==null) {
return null;
} else {
return bht.getCredVal(key);
}
}
-
}