//* Licensed Materials - Property of *
//* IBM *
//* Miracle A/S *
//* Alexandra Instituttet A/S *
//* *
//* eu.abc4trust.pabce.1.34 *
//* *
//* (C) Copyright IBM Corp. 2014. All Rights Reserved. *
//* (C) Copyright Miracle A/S, Denmark. 2014. All Rights Reserved. *
//* (C) Copyright Alexandra Instituttet A/S, Denmark. 2014. All *
//* Rights Reserved. *
//* US Government Users Restricted Rights - Use, duplication or *
//* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. *
//* *
//* This file is 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. See the License for the *
//* specific language governing permissions and limitations *
//* under the License. *
//*/**/****************************************************************
package eu.abc4trust.ri.service.issuer;
import java.io.File;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXBElement;
import eu.abc4trust.ri.servicehelper.FileSystem;
import eu.abc4trust.ri.servicehelper.issuer.CryptoTechnology;
import eu.abc4trust.ri.servicehelper.issuer.IssuanceHelper;
import eu.abc4trust.ri.servicehelper.issuer.SpecAndPolicy;
import eu.abc4trust.ri.servicehelper.user.UserHelper;
import eu.abc4trust.ri.servicehelper.verifier.VerificationHelper;
import eu.abc4trust.xml.IssuanceMessage;
import eu.abc4trust.xml.IssuanceMessageAndBoolean;
import eu.abc4trust.xml.ObjectFactory;
import eu.abc4trust.xml.RevocationAuthorityParameters;
import eu.abc4trust.xml.util.XmlUtils;
@Path("/issue")
public class IssuanceService {
public static final String IDCARD_IDEMIX = "IDCARD_IDEMIX";
public static final String IDCARD_UPROVE = "IDCARD_UPROVE";
// private static final String CREDITCARD_VISA = "creditcardVisa";
// private static final String CREDITCARD_AMEX = "creditcardAmex";
// private static final String PASSPORT_CH = "passportCH";
// private static final String STUDENTCARD = "studentcard";
public static final String UNIVERSITY_IDEMIX = "UNIVERSITY_IDEMIX";
public static final String UNIVERSITY_UPROVE = "UNIVERSITY_UPROVE";
public static final String COURCE_IDEMIX = "COURSE_IDEMIX";
public static final String COURCE_UPROVE = "COURSE_UPROVE";
public static final String SODERHAMN_SCHOOL_IDEMIX = "SCHOOL_IDEMIX";
public static final String SODERHAMN_SCHOOL_UPROVE = "SCHOOL_UPROVE";
public static final String SODERHAMN_SUBJECT_IDEMIX = "SUBJECT_IDEMIX";
public static final String SODERHAMN_SUBJECT_UPROVE = "SUBJECT_UPROVE";
ObjectFactory of = new ObjectFactory();
public IssuanceService() {
System.out.println("IssuanceService ");
initIssuanceHelper();
}
private void initIssuanceHelper() {
if(IssuanceHelper.isInit()) {
System.out.println("IssuanceHelper - already - init!");
return;
}
try {
IssuanceHelper.resetInstance();
System.out.println("IssuanceHelper - try to - init!");
String fileStoragePrefix; // = "issuer_";
String folderName;
if (new File("target").exists()) {
fileStoragePrefix = "target/issuer_";
folderName = "target";
} else {
fileStoragePrefix = "integration-test-issuer/target/issuer_";
folderName = "integration-test-issuer/target";
}
SpecAndPolicy idcard_idemix =
new SpecAndPolicy(IDCARD_IDEMIX,
CryptoTechnology.IDEMIX,
42,
0,
"/eu/abc4trust/sampleXml/credspecs/credentialSpecificationSimpleIdentitycard.xml",
"/eu/abc4trust/sampleXml/issuance/issuancePolicySimpleIdentitycard.xml");
// SpecAndPolicy idcard_uprove =
// new SpecAndPolicy(IDCARD_UPROVE,
// CryptoTechnology.UPROVE,
// 42,
// 10,
// "/eu/abc4trust/sampleXml/credspecs/credentialSpecificationSimpleIdentitycard.xml",
// "/eu/abc4trust/sampleXml/issuance/issuancePolicySimpleIdentitycard.xml");
//
// SpecAndPolicy universityIdemix =
// new SpecAndPolicy(UNIVERSITY_IDEMIX,
// CryptoTechnology.IDEMIX,
// 6,
// 0,
// "/eu/abc4trust/sampleXml/patras/credentialSpecificationPatrasUniversity.xml",
// "/eu/abc4trust/sampleXml/patras/issuancePolicyPatrasUniversity.xml");
// SpecAndPolicy universityUProve =
// new SpecAndPolicy(UNIVERSITY_UPROVE,
// CryptoTechnology.UPROVE,
// 6,
// 10,
// "/eu/abc4trust/sampleXml/patras/credentialSpecificationPatrasUniversity.xml",
// "/eu/abc4trust/sampleXml/patras/issuancePolicyPatrasUniversity.xml");
// SpecAndPolicy courceIdemix =
// new SpecAndPolicy(COURCE_IDEMIX,
// CryptoTechnology.IDEMIX,
// 2,
// 0,
// "/eu/abc4trust/sampleXml/patras/credentialSpecificationPatrasCourse.xml",
// "/eu/abc4trust/sampleXml/patras/issuancePolicyPatrasCourse.xml");
// SpecAndPolicy courceUProve =
// new SpecAndPolicy(COURCE_UPROVE,
// CryptoTechnology.UPROVE,
// 2,
// 1,
// "/eu/abc4trust/sampleXml/patras/credentialSpecificationPatrasCourse.xml",
// "/eu/abc4trust/sampleXml/patras/issuancePolicyPatrasCourse.xml");
String systemAndIssuerParamsPrefix = fileStoragePrefix;
// Create a list to allow for rev auth parameters to be passed
SpecAndPolicy[] specsAndPolicies = {idcard_idemix}; // , idcard_uprove, universityIdemix, universityUProve, courceIdemix, courceUProve}; // , soderhamnSchoolIdemix, soderhamnSchoolUProve, soderhamnSubjectIdemix, soderhamnSubjectUProve};
List<RevocationAuthorityParameters> revAuthParams = FileSystem.findAndLoadXmlResourcesInDir(folderName, "revocation_authority");
IssuanceHelper.initInstance(1024, systemAndIssuerParamsPrefix, fileStoragePrefix, specsAndPolicies, revAuthParams);
System.out.println("IssuanceHelper - done!");
} catch (Exception e) {
System.out.println("Create Domain FAILED " + e);
e.printStackTrace();
}
}
@GET()
@Path("/init")
@Produces(MediaType.TEXT_PLAIN)
public String init() {
System.out.println("issuance service / IssuanceHelper...");
return "OK";
}
@GET()
@Path("/register")
@Produces(MediaType.TEXT_PLAIN)
public String register(@QueryParam("pseudonym") String pseudonym) throws Exception {
System.out.println("issuance service - register pseudonym : " + pseudonym);
BigInteger val = new BigInteger(pseudonym);
IssuanceHelper.getInstance().registerSmartcardScopeExclusivePseudonym(val);
return "OK";
}
@GET()
@Path("/reset")
@Produces(MediaType.TEXT_PLAIN)
public String reset() {
System.out.println("Service Reset");
IssuanceHelper.resetInstance();
UserHelper.resetInstance();
VerificationHelper.resetInstance();
return "OK";
}
@GET()
@Path("/start/{CredentialRequest}")
@Consumes({MediaType.APPLICATION_XML, MediaType.TEXT_XML})
@Produces(MediaType.TEXT_XML)
public JAXBElement<IssuanceMessage> start(
@PathParam("CredentialRequest") final String credentialRequest,
@QueryParam("variant") String variant, @QueryParam("user") String user) throws Exception {
System.out.println("IssuanceService - start - credentialRequest : " + credentialRequest);
System.out.println("- variant : " + variant);
System.out.println("- user : " + user);
Map<String, Object> attributeValueMap = new HashMap<String, Object>();
String credspecAndPolicyKey;
// TODO - add more cases
if (credentialRequest.startsWith("IDCARD")) {
if ("alice".equals(user)) {
attributeValueMap.put("FirstName", "Alice");
attributeValueMap.put("LastName", "Nexdoor");
Calendar bd = Calendar.getInstance();
bd.set(1970, 1, 1, 0, 0, 0);
attributeValueMap.put("Birthday", bd);
} else if ("stewart".equals(user)) {
attributeValueMap.put("FirstName", "Stewart");
attributeValueMap.put("LastName", "Dent");
Calendar bd = Calendar.getInstance();
bd.set(1995, 1, 1, 0, 0, 0);
attributeValueMap.put("Birthday", bd);
} else {
throw new IllegalStateException("IDCard issuance only defined for alice and stewart!");
}
// select witch credspec + policy to use in helper
credspecAndPolicyKey = credentialRequest.toUpperCase();
// } else if ("passport".equals(credentialRequest)) {
// if (!"ch".equals(variant)) {
// throw new IllegalStateException("Passport - only 'ch' passports supported..");
// }
//
// if ("stewart".equals(user)) {
// attributeValueMap.put("http://abc4trust.eu/wp2/abcschemav1.0/revocationhandle",
// "http://admin.ch/passport/revocation/parameters");
// attributeValueMap.put("Name", "Stewart");
// attributeValueMap.put("LastName", "Dent");
// attributeValueMap.put("PassportNumber", 1);
// Calendar cal = Calendar.getInstance();
// cal.set(2012, 1, 1, 0, 0, 0);
// attributeValueMap.put("Issued", cal.getTime());
// cal.set(2015, 1, 1, 0, 0, 0);
// attributeValueMap.put("Expires", cal.getTime());
// attributeValueMap.put("IssuedBy", "service_issuer_integration_test");
//
// } else if ("alice".equals(user)) {
// attributeValueMap.put("http://abc4trust.eu/wp2/abcschemav1.0/revocationhandle",
// "http://admin.ch/passport/revocation/parameters");
// attributeValueMap.put("Name", "Alice");
// attributeValueMap.put("LastName", "Nextdoor");
// attributeValueMap.put("PassportNumber", 42);
// Calendar cal = Calendar.getInstance();
// cal.set(2011, 1, 1, 0, 0, 0);
// attributeValueMap.put("Issued", cal.getTime());
// cal.set(2014, 1, 1, 0, 0, 0);
// attributeValueMap.put("Expires", cal.getTime());
// attributeValueMap.put("IssuedBy", "service_issuer_integration_test");
// } else {
// throw new IllegalStateException("Passport - user not defined in testcase : " + user);
// }
//
// // select witch credspec + policy to use in helper
// credspecAndPolicyKey = PASSPORT_CH;
// } else if ("creditcard".equals(credentialRequest)) {
// if ("visa".equals(variant)) {
// credspecAndPolicyKey = CREDITCARD_VISA;
// attributeValueMap.put("http://abc4trust.eu/wp2/abcschemav1.0/revocationhandle",
// "http://visa.com/creditcard/revocation/parameters");
// } else if ("amex".equals(variant)) {
// credspecAndPolicyKey = CREDITCARD_AMEX;
// attributeValueMap.put("http://abc4trust.eu/wp2/abcschemav1.0/revocationhandle",
// "http://amex.com/amexcard/revocation/parameters");
// } else {
// throw new IllegalStateException("Creditcard - unknow variant : " + variant);
// }
//
// if ("stewart".equals(user)) {
// attributeValueMap.put("CardType", "Normal");
// attributeValueMap.put("Name", "Stewart");
// attributeValueMap.put("LastName", "Dent");
// attributeValueMap.put("CardNumber", 1);
// Calendar cal = Calendar.getInstance();
// cal.set(2015, 1, 1, 0, 0, 0);
// attributeValueMap.put("ExpirationDate", cal.getTime());
// attributeValueMap.put("SecurityCode", 1);
// attributeValueMap.put("Status", "status");
//
// } else if ("alice".equals(user)) {
// attributeValueMap.put("CardType", "Gold");
// attributeValueMap.put("Name", "Alice");
// attributeValueMap.put("LastName", "Nextdoor");
// attributeValueMap.put("CardNumber", 42);
// Calendar cal = Calendar.getInstance();
// cal.set(2014, 1, 1, 0, 0, 0);
// attributeValueMap.put("ExpirationDate", cal.getTime());
// attributeValueMap.put("SecurityCode", 42);
// attributeValueMap.put("Status", "status");
// } else {
// throw new IllegalStateException("Creditcard - user not defined in testcase : " + user);
// }
// } else if ("studentcard".equals(credentialRequest)) {
//
// if ("stewart".equals(user)) {
// /*
// * <abc:AttributeDescription Type="http://abc4trust.eu/wp2/abcschemav1.0/revocationhandle"
// * DataType="xs:string" Encoding="UTF-8"/> <abc:AttributeDescription Type="Name"
// * DataType="xs:string" Encoding="UTF-8"/> <abc:AttributeDescription Type="LastName"
// * DataType="xs:string" Encoding="UTF-8"/> <abc:AttributeDescription Type="StudentNumber"
// * DataType="xs:integer" Encoding="UTF-8"/> <abc:AttributeDescription Type="Issued"
// * DataType="xs:dateTime" Encoding="UTF-8"/> <abc:AttributeDescription Type="Expires"
// * DataType="xs:dateTime" Encoding="UTF-8"/> <abc:AttributeDescription Type="IssuedBy"
// * DataType="xs:string" Encoding="UTF-8"/>
// */
// attributeValueMap.put("http://abc4trust.eu/wp2/abcschemav1.0/revocationhandle",
// "http://www.ethz.ch/studentid/revocation/parameters");
// attributeValueMap.put("Name", "Stewart");
// attributeValueMap.put("LastName", "Dent");
// attributeValueMap.put("StudentNumber", 1);
// Calendar cal = Calendar.getInstance();
// cal.set(2012, 1, 1, 0, 0, 0);
// attributeValueMap.put("Issued", cal.getTime());
// cal.set(2015, 1, 1, 0, 0, 0);
// attributeValueMap.put("Expires", cal.getTime());
// attributeValueMap.put("IssuedBy", "IssuedBy");
//
// } else {
// throw new IllegalStateException("Studentcard - user not defined in testcase : " + user);
// }
// credspecAndPolicyKey = STUDENTCARD;
} else {
throw new IllegalStateException(
"Unknown credential. For now only 'idcard', 'passport', 'creditcard' and 'studentcard' are supported.."
+ credentialRequest);
}
IssuanceMessage im_with_policy;
try {
System.out.println(" - invoke ABCE - using IssuanceHelper! " + credspecAndPolicyKey + " : "
+ attributeValueMap);
im_with_policy =
IssuanceHelper.getInstance().initIssuance(credspecAndPolicyKey, attributeValueMap);
} catch (Exception e) {
e.printStackTrace();
System.err.println(" - failed to initIssuanceProtocol - using IssuanceHelper!");
throw new IllegalStateException("Failed to initIssuanceProtocol - using IssuanceHelper!");
}
System.out.println(" - return inital message - for context : " + im_with_policy.getContext());
System.out.println(" - return inital message : " + XmlUtils.toXml(this.of.createIssuanceMessage(im_with_policy)));
return this.of.createIssuanceMessage(im_with_policy);
}
@POST()
@Path("/step")
@Consumes({MediaType.APPLICATION_XML, MediaType.TEXT_XML})
@Produces(MediaType.TEXT_XML)
public JAXBElement<IssuanceMessage> issueStep(final JAXBElement<IssuanceMessage> issuanceMessage_jb) throws Exception {
IssuanceMessage issuanceMessage = issuanceMessage_jb.getValue();
System.out.println("IssuanceService - step - request - context : " + issuanceMessage.getContext());
System.out.println(" - step - request from client : " + XmlUtils.toXml(this.of.createIssuanceMessage(issuanceMessage)));
IssuanceMessageAndBoolean response;
try {
response = IssuanceHelper.getInstance().issueStep(issuanceMessage);
} catch (Exception e) {
System.err
.println("- got Exception from IssuaceHelper/ABCE Engine - processing IssuanceMessage from user...");
e.printStackTrace();
throw new IllegalStateException("Failed to proces IssuanceMessage from server");
}
if (response.isLastMessage()) {
System.out.println(" - last message for context : "
+ response.getIssuanceMessage().getContext());
try {
System.out.println(" - IssuanceMessage : "
+ XmlUtils.toXml(this.of.createIssuanceMessage(response
.getIssuanceMessage())));
} catch (Exception e) {
System.out.println(" - IssuanceMessage - LOG FAILED!: ");
e.printStackTrace();
}
} else {
System.out.println(" - more steps context : "
+ response.getIssuanceMessage().getContext());
}
System.out.println(" - step - response to client : "
+ XmlUtils.toXml(this.of.createIssuanceMessage(response
.getIssuanceMessage())));
return this.of.createIssuanceMessage(response.getIssuanceMessage());
}
// PATRAS DEMO ISSUANCE
@GET()
@Path("/startPatras/{CredentialRequest}")
@Consumes({MediaType.APPLICATION_XML, MediaType.TEXT_XML})
@Produces(MediaType.TEXT_XML)
public JAXBElement<IssuanceMessage> startUniversity(
@PathParam("CredentialRequest") final String credentialRequest,
@QueryParam("matriculationnumber") int matriculationnumber) throws Exception {
System.out.println("IssuanceService - start - issue University Credential: "
+ credentialRequest);
System.out.println("- Matriculationnumber : " + matriculationnumber);
Map<String, Object> attributeValueMap = new HashMap<String, Object>();
if (credentialRequest.startsWith("UNIVERSITY")) {
attributeValueMap.put("urn:patras:credspec:credUniv:university", "Patras");
attributeValueMap.put("urn:patras:credspec:credUniv:department", "CTI");
attributeValueMap.put("urn:patras:credspec:credUniv:matriculationnr", matriculationnumber);
if (matriculationnumber == 42) {
attributeValueMap.put("urn:patras:credspec:credUniv:firstname", "Stewart");
attributeValueMap.put("urn:patras:credspec:credUniv:lastname", "Dent");
} else if (matriculationnumber == 1235332) {
attributeValueMap.put("urn:patras:credspec:credUniv:firstname", "John");
attributeValueMap.put("urn:patras:credspec:credUniv:lastname", "Doe");
} else if (matriculationnumber == 666) {
attributeValueMap.put("urn:patras:credspec:credUniv:firstname", "Eve");
attributeValueMap.put("urn:patras:credspec:credUniv:lastname", "Cheater");
} else {
throw new IllegalStateException(
"Matriculationnumber issuance only defined for john(1235332), stewart (42) + Eve (666)!");
}
} else if (credentialRequest.startsWith("COURSE")) {
if ((matriculationnumber == 42) || (matriculationnumber == 1235332) || (matriculationnumber == 666)) {
// ok - matriculationnumber accepted...
attributeValueMap.put("urn:patras:credspec:credCourse:courseid", "The-very-cool-course");
} else {
throw new IllegalStateException(
"Matriculationnumber issuance only defined for john(1235332) and stewart (42)!");
}
} else {
throw new IllegalStateException(
"Unknown credentialRequest. For now only 'UNIVERSITY_<technology> and COURSE_<technology> are supported.."
+ credentialRequest);
}
// attributeValueMap.put("urn:patras:credspec:credCourse:matriculationnr", matriculationnumber);
return this.finishStartIssuance(credentialRequest, attributeValueMap);
}
// SODERHAMN DEMO ISSUANCE
@GET()
@Path("/startSoderhamn/{CredentialRequest}")
@Consumes({MediaType.APPLICATION_XML, MediaType.TEXT_XML})
@Produces(MediaType.TEXT_XML)
public JAXBElement<IssuanceMessage> startSchool(
@PathParam("CredentialRequest") final String credentialRequest,
@QueryParam("pupil") String pupil) throws Exception {
System.out.println("IssuanceService - start - issue School Credential: "
+ credentialRequest);
System.out.println("- Pupil : " + pupil);
Map<String, Object> attributeValueMap = new HashMap<String, Object>();
if (credentialRequest.startsWith("SCHOOL")) {
if("Emil".equalsIgnoreCase(pupil)) {
// School credential
System.out.println("Issue Soderhamn School Credential!");
attributeValueMap.put("urn:soderhamn:credspec:credSchool:firstname", "Emil");
attributeValueMap.put("urn:soderhamn:credspec:credSchool:lastname", "von Katthult Svensson");
attributeValueMap.put("urn:soderhamn:credspec:credSchool:civicRegistrationNumber", "42");
attributeValueMap.put("urn:soderhamn:credspec:credSchool:gender", "M");
attributeValueMap.put("urn:soderhamn:credspec:credSchool:schoolname", "L\u00f6nneberga");
Calendar cal = Calendar.getInstance();
cal.set(2000, 01, 10);
SimpleDateFormat xmlDateFormat = new SimpleDateFormat("yyyy-MM-dd'Z'");
String dateValue = xmlDateFormat.format(cal.getTime());
attributeValueMap.put("urn:soderhamn:credspec:credSchool:birthdate", dateValue);
} else {
throw new IllegalStateException(
"Pupil (name) supported : 'Emil'!");
}
} else if (credentialRequest.startsWith("SUBJECT")) {
String subject;
if("Emil".equalsIgnoreCase(pupil)) {
subject = "French";
// attributeValueMap.put("urn:soderhamn:credspec:credSubject:subject", "French");
} else {
throw new IllegalStateException(
"Pupil (name) supported : 'Emil'!");
}
attributeValueMap.put("urn:soderhamn:credspec:credSubject:maths" , "maths".equals(subject));
attributeValueMap.put("urn:soderhamn:credspec:credSubject:physics" , "physics".equals(subject));
attributeValueMap.put("urn:soderhamn:credspec:credSubject:English" , "English".equals(subject));
attributeValueMap.put("urn:soderhamn:credspec:credSubject:French" , "French".equals(subject));
attributeValueMap.put("urn:soderhamn:credspec:credSubject:subject1" , "subject1".equals(subject));
attributeValueMap.put("urn:soderhamn:credspec:credSubject:subject2" , "subject2".equals(subject));
attributeValueMap.put("urn:soderhamn:credspec:credSubject:subject3" , "subject3".equals(subject));
attributeValueMap.put("urn:soderhamn:credspec:credSubject:subject4" , "subject4".equals(subject));
attributeValueMap.put("urn:soderhamn:credspec:credSubject:subject5" , "subject5".equals(subject));
}
return this.finishStartIssuance(credentialRequest, attributeValueMap);
}
private JAXBElement<IssuanceMessage> finishStartIssuance(String specAndPolicyId,
Map<String, Object> attributeValueMap) throws Exception {
IssuanceMessage im_with_policy;
try {
System.out.println(" - invoke ABCE - using IssuanceHelper! " + specAndPolicyId + " : "
+ attributeValueMap);
im_with_policy =
IssuanceHelper.getInstance().initIssuance(specAndPolicyId, attributeValueMap);
} catch (Exception e) {
e.printStackTrace();
System.err.println(" - failed to initIssuanceProtocol - using IssuanceHelper!");
throw new IllegalStateException("Failed to initIssuanceProtocol - using IssuanceHelper!");
}
System.out.println(" - return inital message - for context : " + im_with_policy.getContext());
System.out.println(" - return inital message : " + XmlUtils.toXml(this.of.createIssuanceMessage(im_with_policy)));
return this.of.createIssuanceMessage(im_with_policy);
}
}