summaryrefslogtreecommitdiffstats
path: root/auth/auth-certman/src/main
diff options
context:
space:
mode:
authorInstrumental <jonathan.gathman@att.com>2018-07-19 13:29:32 -0500
committerInstrumental <jonathan.gathman@att.com>2018-07-19 13:29:44 -0500
commit32cdd553a8668e6d03a9cf5b11b360d35a63c87f (patch)
tree48c02e4be820d87efb777d7be20bad57d517b61c /auth/auth-certman/src/main
parent9c8a8b0926b13b07fb1e5394903401e7a3f1ff79 (diff)
Configuration and Auto-Certificates
Issue-ID: AAF-378 Change-Id: Ic820a4e43684a6130f00b28b415a974876099fc3 Signed-off-by: Instrumental <jonathan.gathman@att.com>
Diffstat (limited to 'auth/auth-certman/src/main')
-rw-r--r--auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/CA.java12
-rw-r--r--auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/BCFactory.java2
-rw-r--r--auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/CSRMeta.java1
-rw-r--r--auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/facade/FacadeImpl.java79
-rw-r--r--auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java550
5 files changed, 333 insertions, 311 deletions
diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/CA.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/CA.java
index e840ef56..f1f70a7e 100644
--- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/CA.java
+++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/CA.java
@@ -57,20 +57,22 @@ public abstract class CA {
private final String name;
private final String env;
private MessageDigest messageDigest;
+ private final String permNS;
private final String permType;
private final ArrayList<String> idDomains;
private String[] trustedCAs;
private String[] caIssuerDNs;
- private List<RDN> rdns;
+ private List<RDN> rdns;
protected CA(Access access, String caName, String env) throws IOException, CertException {
trustedCAs = new String[4]; // starting array
this.name = caName;
this.env = env;
- permType = access.getProperty(CM_CA_PREFIX + name + ".perm_type",null);
+ permNS = CM_CA_PREFIX + name;
+ permType = access.getProperty(permNS + ".perm_type",null);
if(permType==null) {
- throw new CertException(CM_CA_PREFIX + name + ".perm_type" + MUST_EXIST_TO_CREATE_CSRS_FOR + caName);
+ throw new CertException(permNS + ".perm_type" + MUST_EXIST_TO_CREATE_CSRS_FOR + caName);
}
caIssuerDNs = Split.splitTrim(':', access.getProperty(Config.CADI_X509_ISSUERS, null));
@@ -204,6 +206,10 @@ public abstract class CA {
}
+ public String getPermNS() {
+ return permNS;
+ }
+
public String getPermType() {
return permType;
}
diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/BCFactory.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/BCFactory.java
index 70ddd438..e40a7a21 100644
--- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/BCFactory.java
+++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/BCFactory.java
@@ -116,7 +116,7 @@ public class BCFactory extends Factory {
CertmanValidator v = new CertmanValidator();
if(v.nullOrBlank("cn", csr.cn())
.nullOrBlank("mechID", csr.mechID())
- .nullOrBlank("email", csr.email())
+// .nullOrBlank("email", csr.email())
.err()) {
return v.errs();
} else {
diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/CSRMeta.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/CSRMeta.java
index 7d417d5f..f9fcad17 100644
--- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/CSRMeta.java
+++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/CSRMeta.java
@@ -156,6 +156,7 @@ public class CSRMeta {
Date start = gc.getTime();
gc.add(GregorianCalendar.DAY_OF_MONTH,2);
Date end = gc.getTime();
+ @SuppressWarnings("deprecation")
X509v3CertificateBuilder xcb = new X509v3CertificateBuilder(
x500Name(),
new BigInteger(12,random), // replace with Serialnumber scheme
diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/facade/FacadeImpl.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/facade/FacadeImpl.java
index 794f63a6..98fdf11b 100644
--- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/facade/FacadeImpl.java
+++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/facade/FacadeImpl.java
@@ -32,16 +32,6 @@ import static org.onap.aaf.auth.layer.Result.ERR_Security;
import static org.onap.aaf.auth.layer.Result.OK;
import java.io.IOException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -58,8 +48,6 @@ import org.onap.aaf.auth.env.AuthzEnv;
import org.onap.aaf.auth.env.AuthzTrans;
import org.onap.aaf.auth.layer.Result;
import org.onap.aaf.cadi.aaf.AAFPermission;
-import org.onap.aaf.cadi.configure.CertException;
-import org.onap.aaf.cadi.configure.Factory;
import org.onap.aaf.misc.env.APIException;
import org.onap.aaf.misc.env.Data;
import org.onap.aaf.misc.env.Env;
@@ -232,10 +220,17 @@ public abstract class FacadeImpl<REQ,CERT,ARTIFACTS,ERROR> extends org.onap.aaf.
@Override
public Result<Void> check(AuthzTrans trans, HttpServletResponse resp, String perm) throws IOException {
String[] p = Split.split('|',perm);
- if(p.length!=3) {
- return Result.err(Result.ERR_BadData,"Invalid Perm String");
+ AAFPermission ap;
+ switch(p.length) {
+ case 3:
+ ap = new AAFPermission(null, p[0],p[1],p[2]);
+ break;
+ case 4:
+ ap = new AAFPermission(p[0],p[1],p[2],p[3]);
+ break;
+ default:
+ return Result.err(Result.ERR_BadData,"Invalid Perm String");
}
- AAFPermission ap = new AAFPermission(p[0],p[1],p[2]);
if(certman.aafLurPerm.fish(trans.getUserPrincipal(), ap)) {
resp.setContentType(voidResp);
resp.getOutputStream().write(0);
@@ -360,33 +355,33 @@ public abstract class FacadeImpl<REQ,CERT,ARTIFACTS,ERROR> extends org.onap.aaf.
// return Result.ok();
}
- private KeyStore keystore(AuthzTrans trans, CertResp cr, String[] trustChain, String name, char[] cap) throws KeyStoreException, CertificateException, APIException, IOException, CertException, NoSuchAlgorithmException {
- KeyStore jks = KeyStore.getInstance("jks");
- jks.load(null, cap);
-
- // Get the Cert(s)... Might include Trust store
- List<String> lcerts = new ArrayList<>();
- lcerts.add(cr.asCertString());
- for(String s : trustChain) {
- lcerts.add(s);
- }
-
- Collection<? extends Certificate> certColl = Factory.toX509Certificate(lcerts);
- X509Certificate[] certs = new X509Certificate[certColl.size()];
- certColl.toArray(certs);
- KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(cap);
-
- PrivateKey pk = Factory.toPrivateKey(trans, cr.privateString());
- KeyStore.PrivateKeyEntry pkEntry =
- new KeyStore.PrivateKeyEntry(pk, new Certificate[] {certs[0]});
- jks.setEntry(name, pkEntry, protParam);
-
- int i=0;
- for(X509Certificate x509 : certs) {
- jks.setCertificateEntry("cert_"+ ++i, x509);
- }
- return jks;
- }
+// private KeyStore keystore(AuthzTrans trans, CertResp cr, String[] trustChain, String name, char[] cap) throws KeyStoreException, CertificateException, APIException, IOException, CertException, NoSuchAlgorithmException {
+// KeyStore jks = KeyStore.getInstance("jks");
+// jks.load(null, cap);
+//
+// // Get the Cert(s)... Might include Trust store
+// List<String> lcerts = new ArrayList<>();
+// lcerts.add(cr.asCertString());
+// for(String s : trustChain) {
+// lcerts.add(s);
+// }
+//
+// Collection<? extends Certificate> certColl = Factory.toX509Certificate(lcerts);
+// X509Certificate[] certs = new X509Certificate[certColl.size()];
+// certColl.toArray(certs);
+// KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(cap);
+//
+// PrivateKey pk = Factory.toPrivateKey(trans, cr.privateString());
+// KeyStore.PrivateKeyEntry pkEntry =
+// new KeyStore.PrivateKeyEntry(pk, new Certificate[] {certs[0]});
+// jks.setEntry(name, pkEntry, protParam);
+//
+// int i=0;
+// for(X509Certificate x509 : certs) {
+// jks.setCertificateEntry("cert_"+ ++i, x509);
+// }
+// return jks;
+// }
@Override
public Result<Void> renewCert(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, boolean withTrust) {
diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java
index 376ae1b1..f9cd060b 100644
--- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java
+++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java
@@ -58,156 +58,170 @@ import org.onap.aaf.auth.org.Organization;
import org.onap.aaf.auth.org.Organization.Identity;
import org.onap.aaf.auth.org.OrganizationException;
import org.onap.aaf.cadi.Hash;
+import org.onap.aaf.cadi.Permission;
import org.onap.aaf.cadi.aaf.AAFPermission;
+import org.onap.aaf.cadi.config.Config;
import org.onap.aaf.cadi.configure.Factory;
import org.onap.aaf.cadi.util.FQI;
import org.onap.aaf.misc.env.APIException;
import org.onap.aaf.misc.env.util.Chrono;
-
public class CMService {
// If we add more CAs, may want to parameterize
private static final int STD_RENEWAL = 30;
private static final int MAX_RENEWAL = 60;
private static final int MIN_RENEWAL = 10;
-
+
public static final String REQUEST = "request";
+ public static final String IGNORE_IPS = "ignoreIPs";
public static final String RENEW = "renew";
public static final String DROP = "drop";
- public static final String IPS = "ips";
public static final String DOMAIN = "domain";
- private static final String CERTMAN = ".certman";
- private static final String ACCESS = ".access";
-
+ private static final String CERTMAN = "certman";
+ private static final String ACCESS = "access";
+
private static final String[] NO_NOTES = new String[0];
+ private final Permission root_read_permission;
private final CertDAO certDAO;
private final CredDAO credDAO;
private final ArtiDAO artiDAO;
private AAF_CM certman;
-// @SuppressWarnings("unchecked")
+ // @SuppressWarnings("unchecked")
public CMService(final AuthzTrans trans, AAF_CM certman) throws APIException, IOException {
- // Jonathan 4/2015 SessionFilter unneeded... DataStax already deals with Multithreading well
-
- HistoryDAO hd = new HistoryDAO(trans, certman.cluster, CassAccess.KEYSPACE);
+ // Jonathan 4/2015 SessionFilter unneeded... DataStax already deals with
+ // Multithreading well
+
+ HistoryDAO hd = new HistoryDAO(trans, certman.cluster, CassAccess.KEYSPACE);
CacheInfoDAO cid = new CacheInfoDAO(trans, hd);
certDAO = new CertDAO(trans, hd, cid);
credDAO = new CredDAO(trans, hd, cid);
artiDAO = new ArtiDAO(trans, hd, cid);
this.certman = certman;
+
+ root_read_permission=new AAFPermission(
+ trans.getProperty(Config.AAF_ROOT_NS, Config.AAF_ROOT_NS_DEF),
+ "access",
+ "*",
+ "read"
+ );
}
-
- public Result<CertResp> requestCert(final AuthzTrans trans,final Result<CertReq> req, final CA ca) {
- if(req.isOK()) {
- if(req.value.fqdns.isEmpty()) {
- return Result.err(Result.ERR_BadData,"No Machines passed in Request");
+ public Result<CertResp> requestCert(final AuthzTrans trans, final Result<CertReq> req, final CA ca) {
+ if (req.isOK()) {
+
+ if (req.value.fqdns.isEmpty()) {
+ return Result.err(Result.ERR_BadData, "No Machines passed in Request");
}
-
+
String key = req.value.fqdns.get(0);
-
+
// Policy 6: Requester must be granted Change permission in Namespace requested
String mechNS = FQI.reverseDomain(req.value.mechid);
- if(mechNS==null) {
- return Result.err(Status.ERR_Denied, "%s does not reflect a valid AAF Namespace",req.value.mechid);
- }
-
-
- // Disallow non-AAF CA without special permission
- if(!"aaf".equals(ca.getName()) && !trans.fish( new AAFPermission(mechNS+CERTMAN, ca.getName(), REQUEST))) {
- return Result.err(Status.ERR_Denied, "'%s' does not have permission to request Certificates from Certificate Authority '%s'",
- trans.user(),ca.getName());
+ if (mechNS == null) {
+ return Result.err(Status.ERR_Denied, "%s does not reflect a valid AAF Namespace", req.value.mechid);
}
List<String> notes = null;
List<String> fqdns = new ArrayList<>(req.value.fqdns);
-
-
+
String email = null;
try {
Organization org = trans.org();
-
+
+ boolean ignoreIPs = trans.fish(new AAFPermission(mechNS,CERTMAN, ca.getName(), IGNORE_IPS));
+
InetAddress primary = null;
// Organize incoming information to get to appropriate Artifact
- if(!fqdns.isEmpty()) {
+ if (!fqdns.isEmpty()) {
// Accept domain wild cards, but turn into real machines
// Need *domain.com:real.machine.domain.com:san.machine.domain.com:...
- if(fqdns.get(0).startsWith("*")) { // Domain set
- if(!trans.fish(new AAFPermission(ca.getPermType(), ca.getName(), DOMAIN))) {
- return Result.err(Result.ERR_Denied, "Domain based Authorizations (" + fqdns.get(0) + ") requires Exception");
+ if (fqdns.get(0).startsWith("*")) { // Domain set
+ if (!trans.fish(new AAFPermission(null,ca.getPermType(), ca.getName(), DOMAIN))) {
+ return Result.err(Result.ERR_Denied,
+ "Domain based Authorizations (" + fqdns.get(0) + ") requires Exception");
}
-
- //TODO check for Permission in Add Artifact?
+
+ // TODO check for Permission in Add Artifact?
String domain = fqdns.get(0).substring(1);
fqdns.remove(0);
- if(fqdns.isEmpty()) {
- return Result.err(Result.ERR_Denied, "Requests using domain require machine declaration");
- }
-
- InetAddress ia = InetAddress.getByName(fqdns.get(0));
- if(ia==null) {
- return Result.err(Result.ERR_Denied, "Request not made from matching IP matching domain");
- } else if(ia.getHostName().endsWith(domain)) {
- primary = ia;
- }
-
- } else {
- for(String cn : req.value.fqdns) {
+ if (fqdns.isEmpty()) {
+ return Result.err(Result.ERR_Denied, "Requests using domain require machine declaration");
+ }
+
+ if (!ignoreIPs) {
+ InetAddress ia = InetAddress.getByName(fqdns.get(0));
+ if (ia == null) {
+ return Result.err(Result.ERR_Denied,
+ "Request not made from matching IP matching domain");
+ } else if (ia.getHostName().endsWith(domain)) {
+ primary = ia;
+ }
+ }
+
+ } else {
+ for (String cn : req.value.fqdns) {
try {
InetAddress[] ias = InetAddress.getAllByName(cn);
Set<String> potentialSanNames = new HashSet<>();
- for(InetAddress ia1 : ias) {
+ for (InetAddress ia1 : ias) {
InetAddress ia2 = InetAddress.getByAddress(ia1.getAddress());
- if(primary==null && ias.length==1 && trans.ip().equals(ia1.getHostAddress())) {
+ if (primary == null && ias.length == 1 && trans.ip().equals(ia1.getHostAddress())) {
primary = ia1;
- } else if(!cn.equals(ia1.getHostName()) && !ia2.getHostName().equals(ia2.getHostAddress())) {
+ } else if (!cn.equals(ia1.getHostName())
+ && !ia2.getHostName().equals(ia2.getHostAddress())) {
potentialSanNames.add(ia1.getHostName());
}
}
} catch (UnknownHostException e1) {
- return Result.err(Result.ERR_BadData,"There is no DNS lookup for %s",cn);
+ return Result.err(Result.ERR_BadData, "There is no DNS lookup for %s", cn);
}
-
+
}
}
}
-
- if(primary==null) {
- return Result.err(Result.ERR_Denied, "Request not made from matching IP (%s)",trans.ip());
+
+ final String host;
+ if(ignoreIPs) {
+ host = req.value.fqdns.get(0);
+ } else if (primary == null) {
+ return Result.err(Result.ERR_Denied, "Request not made from matching IP (%s)", trans.ip());
+ } else {
+ host = primary.getHostAddress();
}
-
+
ArtiDAO.Data add = null;
- Result<List<ArtiDAO.Data>> ra = artiDAO.read(trans, req.value.mechid,primary.getHostAddress());
- if(ra.isOKhasData()) {
- if(add==null) {
+ Result<List<ArtiDAO.Data>> ra = artiDAO.read(trans, req.value.mechid, host);
+ if (ra.isOKhasData()) {
+ if (add == null) {
add = ra.value.get(0); // single key
}
} else {
- ra = artiDAO.read(trans, req.value.mechid,key);
- if(ra.isOKhasData()) { // is the Template available?
- add = ra.value.get(0);
- add.machine=primary.getHostName();
- for(String s : fqdns) {
- if(!s.equals(add.machine)) {
- add.sans(true).add(s);
- }
- }
- Result<ArtiDAO.Data> rc = artiDAO.create(trans, add); // Create new Artifact from Template
- if(rc.notOK()) {
- return Result.err(rc);
- }
- } else {
- add = ra.value.get(0);
- }
+ ra = artiDAO.read(trans, req.value.mechid, key);
+ if (ra.isOKhasData()) { // is the Template available?
+ add = ra.value.get(0);
+ add.machine = host;
+ for (String s : fqdns) {
+ if (!s.equals(add.machine)) {
+ add.sans(true).add(s);
+ }
+ }
+ Result<ArtiDAO.Data> rc = artiDAO.create(trans, add); // Create new Artifact from Template
+ if (rc.notOK()) {
+ return Result.err(rc);
+ }
+ } else {
+ add = ra.value.get(0);
+ }
}
-
+
// Add Artifact listed FQDNs
- if(add.sans!=null) {
- for(String s : add.sans) {
- if(!fqdns.contains(s)) {
+ if (add.sans != null) {
+ for (String s : add.sans) {
+ if (!fqdns.contains(s)) {
fqdns.add(s);
}
}
@@ -215,134 +229,142 @@ public class CMService {
// Policy 2: If Config marked as Expired, do not create or renew
Date now = new Date();
- if(add.expires!=null && now.after(add.expires)) {
- return Result.err(Result.ERR_Policy,"Configuration for %s %s is expired %s",add.mechid,add.machine,Chrono.dateFmt.format(add.expires));
+ if (add.expires != null && now.after(add.expires)) {
+ return Result.err(Result.ERR_Policy, "Configuration for %s %s is expired %s", add.mechid,
+ add.machine, Chrono.dateFmt.format(add.expires));
}
-
+
// Policy 3: MechID must be current
Identity muser = org.getIdentity(trans, add.mechid);
- if(muser == null) {
- return Result.err(Result.ERR_Policy,"MechID must exist in %s",org.getName());
+ if (muser == null) {
+ return Result.err(Result.ERR_Policy, "MechID must exist in %s", org.getName());
}
-
+
// Policy 4: Sponsor must be current
Identity ouser = muser.responsibleTo();
- if(ouser==null) {
- return Result.err(Result.ERR_Policy,"%s does not have a current sponsor at %s",add.mechid,org.getName());
- } else if(!ouser.isFound() || ouser.mayOwn()!=null) {
- return Result.err(Result.ERR_Policy,"%s reports that %s cannot be responsible for %s",org.getName(),trans.user());
+ if (ouser == null) {
+ return Result.err(Result.ERR_Policy, "%s does not have a current sponsor at %s", add.mechid,
+ org.getName());
+ } else if (!ouser.isFound() || ouser.mayOwn() != null) {
+ return Result.err(Result.ERR_Policy, "%s reports that %s cannot be responsible for %s",
+ org.getName(), trans.user());
}
-
+
// Set Email from most current Sponsor
email = ouser.email();
-
+
// Policy 5: keep Artifact data current
- if(!ouser.fullID().equals(add.sponsor)) {
+ if (!ouser.fullID().equals(add.sponsor)) {
add.sponsor = ouser.fullID();
artiDAO.update(trans, add);
}
-
- // Policy 7: Caller must be the MechID or have specifically delegated permissions
- if(!(trans.user().equals(req.value.mechid) || trans.fish(new AAFPermission(mechNS + CERTMAN, ca.getName() , REQUEST)))) {
- return Result.err(Status.ERR_Denied, "%s must have access to modify x509 certs in NS %s",trans.user(),mechNS);
+
+ // Policy 7: Caller must be the MechID or have specifically delegated
+ // permissions
+ if (!(trans.user().equals(req.value.mechid)
+ || trans.fish(new AAFPermission(mechNS,CERTMAN, ca.getName(), REQUEST)))) {
+ return Result.err(Status.ERR_Denied, "%s must have access to modify x509 certs in NS %s",
+ trans.user(), mechNS);
}
-
+
// Make sure Primary is the first in fqdns
- if(fqdns.size()>1) {
- for(int i=0;i<fqdns.size();++i) {
- if(fqdns.get(i).equals(primary.getHostName())) {
- if(i!=0) {
- String tmp = fqdns.get(0);
- fqdns.set(0, primary.getHostName());
- fqdns.set(i, tmp);
+ if (fqdns.size() > 1) {
+ for (int i = 0; i < fqdns.size(); ++i) {
+ if(primary==null) {
+ trans.error().log("CMService var primary is null");
+ } else {
+ String fg = fqdns.get(i);
+ if (fg!=null && fg.equals(primary.getHostName())) {
+ if (i != 0) {
+ String tmp = fqdns.get(0);
+ fqdns.set(0, primary.getHostName());
+ fqdns.set(i, tmp);
+ }
}
}
}
}
} catch (Exception e) {
+ e.printStackTrace();
trans.error().log(e);
- return Result.err(Status.ERR_Denied,"MechID Sponsorship cannot be determined at this time. Try later");
+ return Result.err(Status.ERR_Denied,
+ "AppID Sponsorship cannot be determined at this time. Try later.");
}
-
+
CSRMeta csrMeta;
try {
- csrMeta = BCFactory.createCSRMeta(
- ca,
- req.value.mechid,
- email,
- fqdns);
+ csrMeta = BCFactory.createCSRMeta(ca, req.value.mechid, email, fqdns);
X509andChain x509ac = ca.sign(trans, csrMeta);
- if(x509ac==null) {
- return Result.err(Result.ERR_ActionNotCompleted,"x509 Certificate not signed by CA");
+ if (x509ac == null) {
+ return Result.err(Result.ERR_ActionNotCompleted, "x509 Certificate not signed by CA");
}
trans.info().printf("X509 Subject: %s", x509ac.getX509().getSubjectDN());
-
+
X509Certificate x509 = x509ac.getX509();
CertDAO.Data cdd = new CertDAO.Data();
- cdd.ca=ca.getName();
- cdd.serial=x509.getSerialNumber();
- cdd.id=req.value.mechid;
- cdd.x500=x509.getSubjectDN().getName();
- cdd.x509=Factory.toString(trans, x509);
+ cdd.ca = ca.getName();
+ cdd.serial = x509.getSerialNumber();
+ cdd.id = req.value.mechid;
+ cdd.x500 = x509.getSubjectDN().getName();
+ cdd.x509 = Factory.toString(trans, x509);
certDAO.create(trans, cdd);
-
+
CredDAO.Data crdd = new CredDAO.Data();
crdd.other = Question.random.nextInt();
- crdd.cred=getChallenge256SaltedHash(csrMeta.challenge(),crdd.other);
+ crdd.cred = getChallenge256SaltedHash(csrMeta.challenge(), crdd.other);
crdd.expires = x509.getNotAfter();
crdd.id = req.value.mechid;
crdd.ns = Question.domain2ns(crdd.id);
crdd.type = CredDAO.CERT_SHA256_RSA;
credDAO.create(trans, crdd);
-
- CertResp cr = new CertResp(trans, ca, x509, csrMeta, x509ac.getTrustChain(),compileNotes(notes));
+
+ CertResp cr = new CertResp(trans, ca, x509, csrMeta, x509ac.getTrustChain(), compileNotes(notes));
return Result.ok(cr);
} catch (Exception e) {
trans.error().log(e);
- return Result.err(Result.ERR_ActionNotCompleted,e.getMessage());
+ return Result.err(Result.ERR_ActionNotCompleted, e.getMessage());
}
} else {
return Result.err(req);
}
}
- public Result<CertResp> renewCert(AuthzTrans trans, Result<CertRenew> renew) {
- if(renew.isOK()) {
- return Result.err(Result.ERR_NotImplemented,"Not implemented yet");
+ public Result<CertResp> renewCert(AuthzTrans trans, Result<CertRenew> renew) {
+ if (renew.isOK()) {
+ return Result.err(Result.ERR_NotImplemented, "Not implemented yet");
} else {
return Result.err(renew);
- }
+ }
}
public Result<Void> dropCert(AuthzTrans trans, Result<CertDrop> drop) {
- if(drop.isOK()) {
- return Result.err(Result.ERR_NotImplemented,"Not implemented yet");
+ if (drop.isOK()) {
+ return Result.err(Result.ERR_NotImplemented, "Not implemented yet");
} else {
return Result.err(drop);
- }
+ }
}
public Result<List<Data>> readCertsByMechID(AuthzTrans trans, String mechID) {
// Policy 1: To Read, must have NS Read or is Sponsor
String ns = Question.domain2ns(mechID);
try {
- if( trans.user().equals(mechID)
- || trans.fish(new AAFPermission(ns + ACCESS, "*", "read"))
- || (trans.org().validate(trans,Organization.Policy.OWNS_MECHID,null,mechID))==null) {
+ if (trans.user().equals(mechID) || trans.fish(new AAFPermission(ns,ACCESS, "*", "read"))
+ || (trans.org().validate(trans, Organization.Policy.OWNS_MECHID, null, mechID)) == null) {
return certDAO.readID(trans, mechID);
} else {
- return Result.err(Result.ERR_Denied,"%s is not the ID, Sponsor or NS Owner/Admin for %s at %s",
- trans.user(),mechID,trans.org().getName());
+ return Result.err(Result.ERR_Denied, "%s is not the ID, Sponsor or NS Owner/Admin for %s at %s",
+ trans.user(), mechID, trans.org().getName());
}
- } catch(OrganizationException e) {
+ } catch (OrganizationException e) {
return Result.err(e);
}
}
public Result<CertResp> requestPersonalCert(AuthzTrans trans, CA ca) {
- if(ca.inPersonalDomains(trans.getUserPrincipal())) {
+ if (ca.inPersonalDomains(trans.getUserPrincipal())) {
Organization org = trans.org();
-
+
// Policy 1: MechID must be current
Identity ouser;
try {
@@ -351,39 +373,36 @@ public class CMService {
trans.error().log(e1);
ouser = null;
}
- if(ouser == null) {
- return Result.err(Result.ERR_Policy,"Requesting User must exist in %s",org.getName());
+ if (ouser == null) {
+ return Result.err(Result.ERR_Policy, "Requesting User must exist in %s", org.getName());
}
-
+
// Set Email from most current Sponsor
-
+
CSRMeta csrMeta;
try {
- csrMeta = BCFactory.createPersonalCSRMeta(
- ca,
- trans.user(),
- ouser.email());
+ csrMeta = BCFactory.createPersonalCSRMeta(ca, trans.user(), ouser.email());
X509andChain x509ac = ca.sign(trans, csrMeta);
- if(x509ac==null) {
- return Result.err(Result.ERR_ActionNotCompleted,"x509 Certificate not signed by CA");
+ if (x509ac == null) {
+ return Result.err(Result.ERR_ActionNotCompleted, "x509 Certificate not signed by CA");
}
X509Certificate x509 = x509ac.getX509();
CertDAO.Data cdd = new CertDAO.Data();
- cdd.ca=ca.getName();
- cdd.serial=x509.getSerialNumber();
- cdd.id=trans.user();
- cdd.x500=x509.getSubjectDN().getName();
- cdd.x509=Factory.toString(trans, x509);
+ cdd.ca = ca.getName();
+ cdd.serial = x509.getSerialNumber();
+ cdd.id = trans.user();
+ cdd.x500 = x509.getSubjectDN().getName();
+ cdd.x509 = Factory.toString(trans, x509);
certDAO.create(trans, cdd);
-
+
CertResp cr = new CertResp(trans, ca, x509, csrMeta, x509ac.getTrustChain(), compileNotes(null));
return Result.ok(cr);
} catch (Exception e) {
trans.error().log(e);
- return Result.err(Result.ERR_ActionNotCompleted,e.getMessage());
+ return Result.err(Result.ERR_ActionNotCompleted, e.getMessage());
}
} else {
- return Result.err(Result.ERR_Denied,trans.user()," not supported for CA",ca.getName());
+ return Result.err(Result.ERR_Denied, trans.user(), " not supported for CA", ca.getName());
}
}
@@ -392,71 +411,69 @@ public class CMService {
//////////////
public Result<Void> createArtifact(AuthzTrans trans, List<ArtiDAO.Data> list) {
CertmanValidator v = new CertmanValidator().artisRequired(list, 1);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
}
- for(ArtiDAO.Data add : list) {
+ for (ArtiDAO.Data add : list) {
try {
// Policy 1: MechID must exist in Org
Identity muser = trans.org().getIdentity(trans, add.mechid);
- if(muser == null) {
- return Result.err(Result.ERR_Denied,"%s is not valid for %s", add.mechid,trans.org().getName());
+ if (muser == null) {
+ return Result.err(Result.ERR_Denied, "%s is not valid for %s", add.mechid, trans.org().getName());
}
-
+
// Policy 2: MechID must have valid Organization Owner
Identity emailUser;
- if(muser.isPerson()) {
+ if (muser.isPerson()) {
emailUser = muser;
} else {
Identity ouser = muser.responsibleTo();
- if(ouser == null) {
- return Result.err(Result.ERR_Denied,"%s is not a valid Sponsor for %s at %s",
- trans.user(),add.mechid,trans.org().getName());
+ if (ouser == null) {
+ return Result.err(Result.ERR_Denied, "%s is not a valid Sponsor for %s at %s", trans.user(),
+ add.mechid, trans.org().getName());
}
// Policy 3: Calling ID must be MechID Owner
- if(!trans.user().equals(ouser.fullID())) {
- return Result.err(Result.ERR_Denied,"%s is not the Sponsor for %s at %s",
- trans.user(),add.mechid,trans.org().getName());
+ if (!trans.user().startsWith(ouser.id())) {
+ return Result.err(Result.ERR_Denied, "%s is not the Sponsor for %s at %s", trans.user(),
+ add.mechid, trans.org().getName());
}
emailUser = ouser;
}
-
- // Policy 4: Renewal Days are between 10 and 60 (constants, may be parameterized)
- if(add.renewDays<MIN_RENEWAL) {
+ // Policy 4: Renewal Days are between 10 and 60 (constants, may be
+ // parameterized)
+ if (add.renewDays < MIN_RENEWAL) {
add.renewDays = STD_RENEWAL;
- } else if(add.renewDays>MAX_RENEWAL) {
+ } else if (add.renewDays > MAX_RENEWAL) {
add.renewDays = MAX_RENEWAL;
}
-
+
// Policy 5: If Notify is blank, set to Owner's Email
- if(add.notify==null || add.notify.length()==0) {
- add.notify = "mailto:"+emailUser.email();
+ if (add.notify == null || add.notify.length() == 0) {
+ add.notify = "mailto:" + emailUser.email();
}
-
+
// Policy 6: Only do Domain by Exception
- if(add.machine.startsWith("*")) { // Domain set
+ if (add.machine.startsWith("*")) { // Domain set
CA ca = certman.getCA(add.ca);
-
- if(!trans.fish(new AAFPermission(ca.getPermType(), add.ca, DOMAIN))) {
- return Result.err(Result.ERR_Denied,"Domain Artifacts (%s) requires specific Permission",
- add.machine);
+ if (!trans.fish(new AAFPermission(ca.getPermNS(),ca.getPermType(), add.ca, DOMAIN))) {
+ return Result.err(Result.ERR_Denied, "Domain Artifacts (%s) requires specific Permission",
+ add.machine);
}
}
// Set Sponsor from Golden Source
add.sponsor = emailUser.fullID();
-
-
+
} catch (OrganizationException e) {
return Result.err(e);
}
// Add to DB
Result<ArtiDAO.Data> rv = artiDAO.create(trans, add);
// TODO come up with Partial Reporting Scheme, or allow only one at a time.
- if(rv.notOK()) {
+ if (rv.notOK()) {
return Result.err(rv);
}
}
@@ -465,40 +482,45 @@ public class CMService {
public Result<List<ArtiDAO.Data>> readArtifacts(AuthzTrans trans, ArtiDAO.Data add) throws OrganizationException {
CertmanValidator v = new CertmanValidator().keys(add);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
}
Result<List<ArtiDAO.Data>> data = artiDAO.read(trans, add);
- if(data.notOKorIsEmpty()) {
+ if (data.notOKorIsEmpty()) {
return data;
}
add = data.value.get(0);
- if( trans.user().equals(add.mechid)
- || trans.fish(new AAFPermission(add.ns + ACCESS, "*", "read"))
- || trans.fish(new AAFPermission(add.ns+CERTMAN,add.ca,"read"))
- || trans.fish(new AAFPermission(add.ns+CERTMAN,add.ca,"request"))
- || (trans.org().validate(trans,Organization.Policy.OWNS_MECHID,null,add.mechid))==null) {
+ if (trans.user().equals(add.mechid)
+ || trans.fish(root_read_permission,
+ new AAFPermission(add.ns,ACCESS, "*", "read"),
+ new AAFPermission(add.ns,CERTMAN, add.ca, "read"),
+ new AAFPermission(add.ns,CERTMAN, add.ca, "request"))
+ || (trans.org().validate(trans, Organization.Policy.OWNS_MECHID, null, add.mechid)) == null) {
return data;
} else {
- return Result.err(Result.ERR_Denied,"%s is not %s, is not the sponsor, and doesn't have delegated permission.",trans.user(),add.mechid,add.ns+".certman|"+add.ca+"|read or ...|request"); // note: reason is set by 2nd case, if 1st case misses
+ return Result.err(Result.ERR_Denied,
+ "%s is not %s, is not the sponsor, and doesn't have delegated permission.", trans.user(),
+ add.mechid, add.ns + ".certman|" + add.ca + "|read or ...|request"); // note: reason is set by 2nd
+ // case, if 1st case misses
}
}
- public Result<List<ArtiDAO.Data>> readArtifactsByMechID(AuthzTrans trans, String mechid) throws OrganizationException {
+ public Result<List<ArtiDAO.Data>> readArtifactsByMechID(AuthzTrans trans, String mechid)
+ throws OrganizationException {
CertmanValidator v = new CertmanValidator();
v.nullOrBlank("mechid", mechid);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
}
String ns = FQI.reverseDomain(mechid);
-
+
String reason;
- if(trans.fish(new AAFPermission(ns + ACCESS, "*", "read"))
- || (reason=trans.org().validate(trans,Organization.Policy.OWNS_MECHID,null,mechid))==null) {
+ if (trans.fish(new AAFPermission(ns, ACCESS, "*", "read"))
+ || (reason = trans.org().validate(trans, Organization.Policy.OWNS_MECHID, null, mechid)) == null) {
return artiDAO.readByMechID(trans, mechid);
} else {
- return Result.err(Result.ERR_Denied,reason); // note: reason is set by 2nd case, if 1st case misses
+ return Result.err(Result.ERR_Denied, reason); // note: reason is set by 2nd case, if 1st case misses
}
}
@@ -506,10 +528,10 @@ public class CMService {
public Result<List<ArtiDAO.Data>> readArtifactsByMachine(AuthzTrans trans, String machine) {
CertmanValidator v = new CertmanValidator();
v.nullOrBlank("machine", machine);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
}
-
+
// TODO do some checks?
Result<List<ArtiDAO.Data>> rv = artiDAO.readByMachine(trans, machine);
@@ -519,43 +541,43 @@ public class CMService {
public Result<List<ArtiDAO.Data>> readArtifactsByNs(AuthzTrans trans, String ns) {
CertmanValidator v = new CertmanValidator();
v.nullOrBlank("ns", ns);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
}
-
+
// TODO do some checks?
- return artiDAO.readByNs(trans, ns);
+ return artiDAO.readByNs(trans, ns);
}
-
public Result<Void> updateArtifact(AuthzTrans trans, List<ArtiDAO.Data> list) throws OrganizationException {
CertmanValidator v = new CertmanValidator();
v.artisRequired(list, 1);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
}
-
+
// Check if requesting User is Sponsor
- //TODO - Shall we do one, or multiples?
- for(ArtiDAO.Data add : list) {
+ // TODO - Shall we do one, or multiples?
+ for (ArtiDAO.Data add : list) {
// Policy 1: MechID must exist in Org
Identity muser = trans.org().getIdentity(trans, add.mechid);
- if(muser == null) {
- return Result.err(Result.ERR_Denied,"%s is not valid for %s", add.mechid,trans.org().getName());
+ if (muser == null) {
+ return Result.err(Result.ERR_Denied, "%s is not valid for %s", add.mechid, trans.org().getName());
}
-
+
// Policy 2: MechID must have valid Organization Owner
Identity ouser = muser.responsibleTo();
- if(ouser == null) {
- return Result.err(Result.ERR_Denied,"%s is not a valid Sponsor for %s at %s",
- trans.user(),add.mechid,trans.org().getName());
+ if (ouser == null) {
+ return Result.err(Result.ERR_Denied, "%s is not a valid Sponsor for %s at %s", trans.user(), add.mechid,
+ trans.org().getName());
}
- // Policy 3: Renewal Days are between 10 and 60 (constants, may be parameterized)
- if(add.renewDays<MIN_RENEWAL) {
+ // Policy 3: Renewal Days are between 10 and 60 (constants, may be
+ // parameterized)
+ if (add.renewDays < MIN_RENEWAL) {
add.renewDays = STD_RENEWAL;
- } else if(add.renewDays>MAX_RENEWAL) {
+ } else if (add.renewDays > MAX_RENEWAL) {
add.renewDays = MAX_RENEWAL;
}
@@ -564,101 +586,99 @@ public class CMService {
add.sponsor = ouser.fullID();
// Policy 5: If Notify is blank, set to Owner's Email
- if(add.notify==null || add.notify.length()==0) {
- add.notify = "mailto:"+ouser.email();
+ if (add.notify == null || add.notify.length() == 0) {
+ add.notify = "mailto:" + ouser.email();
}
// Policy 6: Only do Domain by Exception
- if(add.machine.startsWith("*")) { // Domain set
+ if (add.machine.startsWith("*")) { // Domain set
CA ca = certman.getCA(add.ca);
- if(ca==null) {
+ if (ca == null) {
return Result.err(Result.ERR_BadData, "CA is required in Artifact");
}
- if(!trans.fish(new AAFPermission(ca.getPermType(), add.ca, DOMAIN))) {
- return Result.err(Result.ERR_Denied,"Domain Artifacts (%s) requires specific Permission",
- add.machine);
+ if (!trans.fish(new AAFPermission(null,ca.getPermType(), add.ca, DOMAIN))) {
+ return Result.err(Result.ERR_Denied, "Domain Artifacts (%s) requires specific Permission",
+ add.machine);
}
}
// Policy 7: only Owner may update info
- if(trans.user().equals(add.sponsor)) {
+ if (trans.user().startsWith(ouser.id())) {
return artiDAO.update(trans, add);
} else {
- return Result.err(Result.ERR_Denied,"%s may not update info for %s",trans.user(),muser.fullID());
+ return Result.err(Result.ERR_Denied, "%s may not update info for %s", trans.user(), muser.fullID());
}
}
- return Result.err(Result.ERR_BadData,"No Artifacts to update");
+ return Result.err(Result.ERR_BadData, "No Artifacts to update");
}
-
+
public Result<Void> deleteArtifact(AuthzTrans trans, String mechid, String machine) throws OrganizationException {
CertmanValidator v = new CertmanValidator();
- v.nullOrBlank("mechid", mechid)
- .nullOrBlank("machine", machine);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
+ v.nullOrBlank("mechid", mechid).nullOrBlank("machine", machine);
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
}
Result<List<ArtiDAO.Data>> rlad = artiDAO.read(trans, mechid, machine);
- if(rlad.notOKorIsEmpty()) {
- return Result.err(Result.ERR_NotFound,"Artifact for %s %s does not exist.",mechid,machine);
+ if (rlad.notOKorIsEmpty()) {
+ return Result.err(Result.ERR_NotFound, "Artifact for %s %s does not exist.", mechid, machine);
}
-
- return deleteArtifact(trans,rlad.value.get(0));
+
+ return deleteArtifact(trans, rlad.value.get(0));
}
-
+
private Result<Void> deleteArtifact(AuthzTrans trans, ArtiDAO.Data add) throws OrganizationException {
- // Policy 1: Record should be delete able only by Existing Sponsor.
- String sponsor=null;
+ // Policy 1: Record should be delete able only by Existing Sponsor.
+ String sponsor = null;
Identity muser = trans.org().getIdentity(trans, add.mechid);
- if(muser != null) {
+ if (muser != null) {
Identity ouser = muser.responsibleTo();
- if(ouser!=null) {
+ if (ouser != null) {
sponsor = ouser.fullID();
}
}
- // Policy 1.a: If Sponsorship is deleted in system of Record, then
+ // Policy 1.a: If Sponsorship is deleted in system of Record, then
// accept deletion by sponsor in Artifact Table
- if(sponsor==null) {
+ if (sponsor == null) {
sponsor = add.sponsor;
}
-
+
String ns = FQI.reverseDomain(add.mechid);
- if(trans.fish(new AAFPermission(ns + ACCESS, "*", "write"))
- || trans.user().equals(sponsor)) {
+ if (trans.fish(new AAFPermission(ns,ACCESS, "*", "write")) || trans.user().equals(sponsor)) {
return artiDAO.delete(trans, add, false);
}
- return Result.err(Result.ERR_Denied, "%1 is not allowed to delete this item",trans.user());
+ return Result.err(Result.ERR_Denied, "%1 is not allowed to delete this item", trans.user());
}
public Result<Void> deleteArtifact(AuthzTrans trans, List<ArtiDAO.Data> list) {
CertmanValidator v = new CertmanValidator().artisRequired(list, 1);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
}
try {
boolean partial = false;
- Result<Void> result=null;
- for(ArtiDAO.Data add : list) {
+ Result<Void> result = null;
+ for (ArtiDAO.Data add : list) {
result = deleteArtifact(trans, add);
- if(result.notOK()) {
+ if (result.notOK()) {
partial = true;
}
}
- if(result == null) {
- result = Result.err(Result.ERR_BadData,"No Artifacts to delete");
- } else if(partial) {
+ if (result == null) {
+ result = Result.err(Result.ERR_BadData, "No Artifacts to delete");
+ } else if (partial) {
result.partialContent(true);
}
return result;
- } catch(Exception e) {
+ } catch (Exception e) {
return Result.err(e);
}
}
private String[] compileNotes(List<String> notes) {
String[] rv;
- if(notes==null) {
+ if (notes == null) {
rv = NO_NOTES;
} else {
rv = new String[notes.size()];