//* 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.abce.internal.user.credentialManager;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import javax.xml.bind.JAXBElement;
import com.fasterxml.uuid.Generators;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import eu.abc4trust.cryptoEngine.CredentialWasRevokedException;
import eu.abc4trust.cryptoEngine.CryptoEngineException;
import eu.abc4trust.cryptoEngine.user.CredentialSerializer;
import eu.abc4trust.cryptoEngine.user.CryptoEngineUser;
import eu.abc4trust.cryptoEngine.user.PseudonymSerializer;
import eu.abc4trust.cryptoEngine.user.PseudonymSerializerObjectGzip;
import eu.abc4trust.keyManager.KeyManager;
import eu.abc4trust.smartcard.BasicSmartcard;
import eu.abc4trust.smartcard.CardStorage;
import eu.abc4trust.smartcard.SecretBasedSmartcard;
import eu.abc4trust.smartcard.Smartcard;
import eu.abc4trust.smartcard.SmartcardBlob;
import eu.abc4trust.smartcard.SmartcardStatusCode;
import eu.abc4trust.util.StorageUtil;
import eu.abc4trust.util.TimingsLogger;
import eu.abc4trust.xml.Credential;
import eu.abc4trust.xml.CredentialDescription;
import eu.abc4trust.xml.CredentialSpecification;
import eu.abc4trust.xml.FriendlyDescription;
import eu.abc4trust.xml.IntegerParameter;
import eu.abc4trust.xml.IssuerParameters;
import eu.abc4trust.xml.Parameter;
import eu.abc4trust.xml.Pseudonym;
import eu.abc4trust.xml.PseudonymMetadata;
import eu.abc4trust.xml.PseudonymWithMetadata;
import eu.abc4trust.xml.PublicKey;
import eu.abc4trust.xml.Secret;
import eu.abc4trust.xml.SecretDescription;
import eu.abc4trust.xml.Signature;
import eu.abc4trust.xml.util.XmlUtils;
@Deprecated
// Does not implement username properly
public class CredentialManagerImpl implements CredentialManager {
public static final String PSEUDONYM_PREFIX = "pseudonym_";
private final KeyManager keyManager;
private final CryptoEngineUser cryptoEngineUser;
private final CredentialStorage storage;
private final SecretStorage sstorage;
private final CardStorage cardStorage;
private final Random prng;
private final ImageCache imageCache;
private final CredentialSerializer credentialSerializer;
private final PseudonymSerializer pseudonymSerializer;
// TODO : hgk - FIND SOLUTION : for Soderhamn - save pseudonyms in map - to
// be able to run through presentation when pseudonyms arenot stored on card
private final Map<String, PseudonymWithMetadata> soderhamnTmpPseudonymMap =
new HashMap<String, PseudonymWithMetadata>();
@Inject
public CredentialManagerImpl(CredentialStorage credentialStore, SecretStorage secretStore,
KeyManager keyManager, ImageCache imageCache, CryptoEngineUser cryptoEngineUser,
@Named("RandomNumberGenerator") Random prng, CardStorage cardStorage,
CredentialSerializer serializer) {
// WARNING: Due to circular dependencies you MUST NOT dereference
// cryptoEngineUser
// in this constructor.
// (Guice does some magic to support circular dependencies).
this.keyManager = keyManager;
this.cryptoEngineUser = cryptoEngineUser;
this.storage = credentialStore;
this.cardStorage = cardStorage;
this.sstorage = secretStore;
this.prng = prng;
this.imageCache = imageCache;
// CredentialSerializerDelegator wraps injected optimized serializer for
// Idemix + a standard serializer for UProve
// this.credentialSerializer = new
// CredentialSerializerDelegator(serializer, new
// CredentialSerializerObjectGzip());
// The optimized serializer should also work for UProve now.
this.credentialSerializer = serializer;
this.pseudonymSerializer = new PseudonymSerializerObjectGzip(cardStorage);
}
private URI getSmartcardUri() {
Map<URI, BasicSmartcard> scs = this.cardStorage.getSmartcards();
for (URI uri : scs.keySet()) {
if (!(scs.get(uri) instanceof SecretBasedSmartcard)) {
return uri;
}
}
return null;
}
private URI escapeUri(URI uri) {
if (uri.toString().contains(":") && !uri.toString().contains("_")) {
uri = URI.create(uri.toString().replaceAll(":", "_")); // change all
// ':' to
// '_'
}
return uri;
}
@Override
public void attachMetadataToPseudonym(String username, Pseudonym pseudonym, PseudonymMetadata md)
throws CredentialManagerException {
try {
PseudonymWithMetadata pwm = null;
try {
pwm = this.getPseudonym(username, pseudonym.getPseudonymUID());
} catch (Exception e) {
// pwm not present, creating new.
}
if (pwm != null) {
URI pseudonymUri = pseudonym.getPseudonymUID();
URI SCuri = this.getSmartcardUri();
if (SCuri == null) {
this.storage.deletePseudonymWithMetadata(username, pseudonymUri);
} else {
Smartcard sc = (Smartcard) this.cardStorage.getSmartcard(SCuri);
sc.deletePseudonym(this.cardStorage.getPin(SCuri), pseudonymUri);
}
} else {
pwm = new PseudonymWithMetadata();
pwm.setPseudonym(pseudonym);
}
pwm.setPseudonymMetadata(md);
this.storePseudonym(username, pwm);
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
}
@Override
public Credential getCredential(String username, URI creduid) throws CredentialManagerException {
if (creduid == null) {
throw new CredentialManagerException("Credential UID is null");
}
ObjectInputStream objectInput = null;
ByteArrayInputStream byteArrayInputStream = null;
try {
// System.out.println("CredentialManagerImpl - fetching credential. Looking first in SC.");
for (URI uri : this.cardStorage.getSmartcards().keySet()) {
BasicSmartcard sc = this.cardStorage.getSmartcards().get(uri);
if (sc instanceof Smartcard) {
// System.out.println("CredentialManagerImpl - fetching credential. got a SC. trying to fetch the cred: "
// + creduid);
Credential cred =
sc.getCredential(this.cardStorage.getPin(uri), creduid, this.credentialSerializer);
if (cred != null) {
// We have to supply certain things here since they are
// lost in compression
CredentialDescription descr = cred.getCredentialDescription();
descr.setCredentialUID(creduid);
descr.setSecretReference(uri);
return cred;
}
System.err.println("Fetching credential failed. It was null.. ");
}
}
byte[] tokenBytes = this.storage.getCredential(username, creduid);
if (tokenBytes == null) {
throw new CredentialNotInStorageException("Credential with UID: \"" + creduid
+ "\" is not in storage");
}
byteArrayInputStream = new ByteArrayInputStream(tokenBytes);
objectInput = new ObjectInputStream(byteArrayInputStream);
Credential cred = (Credential) objectInput.readObject();
return cred;
} catch (CredentialNotInStorageException ex) {
throw ex;
} catch (Exception ex) {
throw new CredentialManagerException(ex);
} finally {
// Close the streams.
StorageUtil.closeIgnoringException(objectInput);
StorageUtil.closeIgnoringException(byteArrayInputStream);
}
}
@Override
public List<CredentialDescription> getCredentialDescription(String username, List<URI> issuers,
List<URI> credspecs) throws CredentialManagerException {
List<CredentialDescription> ls = new LinkedList<CredentialDescription>();
try {
List<URI> credUris = this.listCredentials(username);
for (URI credUri : credUris) {
Credential cred = this.getCredential(username, credUri);
CredentialDescription credentialDescription = cred.getCredentialDescription();
if (issuers.contains(credentialDescription.getIssuerParametersUID())) {
if (credspecs.contains(credentialDescription.getCredentialSpecificationUID())) {
// System.out.println("ADDED A CRED DESCRIPTION: " +
// credentialDescription.getCredentialUID());
ls.add(credentialDescription);
}
}
}
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
return ls;
}
@Override
public CredentialDescription getCredentialDescription(String username, URI creduid)
throws CredentialManagerException {
try {
Credential cred = this.getCredential(username, creduid);
CredentialDescription credDesc = cred.getCredentialDescription();
return credDesc;
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
}
private PseudonymWithMetadata parseBytesAsPseudonymWithMetaData(byte[] bytes)
throws CredentialManagerException {
ByteArrayInputStream byteArrayInputStream = null;
ObjectInputStream objectInput = null;
try {
PseudonymWithMetadata pwm = null;
if (bytes != null) {
byteArrayInputStream = new ByteArrayInputStream(bytes);
objectInput = new ObjectInputStream(byteArrayInputStream);
pwm = (PseudonymWithMetadata) objectInput.readObject();
}
return pwm;
} catch (Exception ex) {
throw new CredentialManagerException(ex);
} finally {
// Close the streams.
StorageUtil.closeIgnoringException(objectInput);
StorageUtil.closeIgnoringException(byteArrayInputStream);
}
}
@Override
public boolean hasBeenRevoked(String username, URI creduid, URI revparsuid, List<URI> revokedatts)
throws CredentialManagerException {
Credential cred = this.getCredential(username, creduid);
try {
Credential updatedCred =
this.cryptoEngineUser
.updateNonRevocationEvidence(username, cred, revparsuid, revokedatts);
this.storeCredential(username, updatedCred);
return false;
} catch (CredentialWasRevokedException ex) {
cred.getCredentialDescription().setRevokedByIssuer(true);
this.storeCredential(username, cred);
return true;
} catch (CryptoEngineException ex) {
throw new CredentialManagerException(ex);
}
}
@Override
public boolean hasBeenRevoked(String username, URI creduid, URI revparsuid,
List<URI> revokedatts, URI revinfouid) throws CredentialManagerException {
Credential cred = this.getCredential(username, creduid);
try {
Credential updatedCred =
this.cryptoEngineUser.updateNonRevocationEvidence(username, cred, revparsuid,
revokedatts, revinfouid);
this.storeCredential(username, updatedCred);
return false;
} catch (CredentialWasRevokedException ex) {
cred.getCredentialDescription().setRevokedByIssuer(true);
this.storeCredential(username, cred);
return true;
} catch (CryptoEngineException ex) {
throw new CredentialManagerException(ex);
}
}
@Override
public List<URI> listCredentials(String username) throws CredentialManagerException {
List<URI> ls = new ArrayList<URI>();
try {
if (this.cardStorage.getSmartcards().size() != 0) {
for (URI uri : this.cardStorage.getSmartcards().keySet()) {
BasicSmartcard bsc = this.cardStorage.getSmartcard(uri);
if (bsc instanceof SecretBasedSmartcard) {
break;
}
Smartcard sc = (Smartcard) bsc;
int pin = this.cardStorage.getPin(uri);
Set<URI> setList = sc.listCredentialsUris(pin);
ls.addAll(setList);
return ls;
}
}
return this.storage.listCredentials(username);
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
}
@Override
public URI storeCredential(String username, Credential cred) throws CredentialManagerException {
CredentialDescription credentialDescription = cred.getCredentialDescription();
URI credUid = credentialDescription.getCredentialUID();
if ((credUid == null) || credUid.equals(URI.create(""))) {
UUID uuid = Generators.randomBasedGenerator(this.prng).generate();
credUid = URI.create(uuid.toString());
credentialDescription.setCredentialUID(credUid);
}
this.storeImageAndUpdateCredentialDescription(credentialDescription);
try {
URI issuerParametersUID = cred.getCredentialDescription().getIssuerParametersUID();
IssuerParameters issuerParameters = keyManager.getIssuerParameters(issuerParametersUID);
URI cryptoAlgorithm = issuerParameters.getAlgorithmID();
// if uprove - and # of tokens == 1 - set can reuse to 'true'
if (cryptoAlgorithm.toASCIIString().indexOf("uprove") != -1) {
// PublicKey pk = ((JAXBElement<PublicKey>)
// issuerParameters.getCryptoParams().getContent().get(0)).getValue();
XmlUtils.fixNestedContent(issuerParameters.getCryptoParams());
PublicKey pk = (PublicKey) issuerParameters.getCryptoParams().getContent().get(0);
int numberOfTokens = -1;
String uproveTokensKey = "urn:idmx:3.0.0:issuer:publicKey:uprove:tokens";
for (Parameter p : pk.getParameter()) {
if (uproveTokensKey.equals(p.getName())) {
IntegerParameter ip = (IntegerParameter) p;
numberOfTokens = ip.getValue();
break;
}
}
if (numberOfTokens == 1) {
Object o = cred.getCryptoParams().getContent().get(0);
if (o instanceof JAXBElement<?> && ((JAXBElement<?>) o).getValue() instanceof Signature) {
Signature s = ((JAXBElement<Signature>) o).getValue();
s.setCanReuseToken(true);
}
}
}
} catch (Exception ignore) {}
ByteArrayOutputStream byteArrayOutputStream = null;
ObjectOutputStream objectOutput = null;
try {
URI cardUid = cred.getCredentialDescription().getSecretReference();
BasicSmartcard bsc = this.cardStorage.getSmartcards().get(cardUid);
//if(cardUid == null){
// cardUid = this.getSmartcardUri();
//}
bsc = this.cardStorage.getSmartcards().get(cardUid);
if ((cardUid != null) && (bsc != null) && !(bsc instanceof SecretBasedSmartcard)) {
if (!cred.getCredentialDescription().isRevokedByIssuer()) {
Smartcard sc = (Smartcard) this.cardStorage.getSmartcards().get(cardUid);
TimingsLogger.logTiming("Smartcard.storeCredential("
+ cred.getCredentialDescription().getCredentialSpecificationUID() + ")", true);
SmartcardStatusCode status =
sc.storeCredential(this.cardStorage.getPin(cardUid), credUid, cred,
this.credentialSerializer);
TimingsLogger.logTiming("Smartcard.storeCredential("
+ cred.getCredentialDescription().getCredentialSpecificationUID() + ")", false);
if (status != SmartcardStatusCode.OK) {
throw new CredentialManagerException("Could not store credential. Reason: " + status);
}
return credUid;
} else {
// The cryptoengine does not know if a credential is stored on a smartcard or not.
// During nonrevocation information updates, the credential will be updated and
// therefore saved. In order to save storage, we do not save the credential if
// it is revoked.
throw new CredentialManagerException(
"Tried to store a revoked credential on a smartcard, do nothing");
}
} else {
byteArrayOutputStream = new ByteArrayOutputStream();
objectOutput = new ObjectOutputStream(byteArrayOutputStream);
objectOutput.writeObject(cred);
byte[] credBytes = byteArrayOutputStream.toByteArray();
this.storage.addCredential(username, credUid, credBytes);
}
} catch (Exception ex) {
throw new CredentialManagerException(ex);
} finally {
// Close the streams.
StorageUtil.closeIgnoringException(objectOutput);
StorageUtil.closeIgnoringException(byteArrayOutputStream);
}
return credUid;
}
@Override
public void updateCredential(String username, Credential cred) throws CredentialManagerException {
URI credUid = cred.getCredentialDescription().getCredentialUID();
try {
URI cardUid = cred.getCredentialDescription().getSecretReference();
BasicSmartcard bsc = this.cardStorage.getSmartcards().get(cardUid);
if ((cardUid != null) && (bsc != null) && !(bsc instanceof SecretBasedSmartcard)) {
Smartcard sc = (Smartcard) this.cardStorage.getSmartcards().get(cardUid);
if (cred.getCredentialDescription().isRevokedByIssuer()) {
this.deleteCredential(username, credUid);
} else {
sc.removeCredentialUri(this.cardStorage.getPin(cardUid), credUid);
this.storeCredential(username, cred);
}
} else {
this.deleteCredential(username, credUid);
this.storeCredential(username, cred);
}
} catch (Exception e) {
throw new CredentialManagerException(e);
}
}
private void storeImageAndUpdateCredentialDescription(CredentialDescription credentialDescription)
throws CredentialManagerException {
try {
URI imageRef = credentialDescription.getImageReference();
URL url = this.imageCache.getDefaultImage();
if (imageRef != null) {
url = this.imageCache.storeImage(credentialDescription.getImageReference());
}
try {
String urlString = "" + url;
if (urlString.contains(" ")) {
URL fixed = new URL(("" + url).replaceAll(" ", "%20"));
url = fixed;
}
} catch (Exception e) {
System.err.println("storeImageAndUpdateCredentialDescription - fix failed : " + url + " : "
+ e);
}
// System.out.println("storeImageAndUpdateCredentialDescription : "
// + url);
credentialDescription.setImageReference(url.toURI());
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
}
@Override
public void storePseudonym(String username, PseudonymWithMetadata pwm)
throws CredentialManagerException {
Pseudonym pseudonym = pwm.getPseudonym();
ByteArrayOutputStream byteArrayOutputStream = null;
ObjectOutputStream objectOutput = null;
try {
URI pseudonymUri = pseudonym.getPseudonymUID();
URI scUri = this.getSmartcardUri();
// System.out.println("Store pseudonym: " + pseudonymUri + ", on: " + scUri);
// pseudonymUri.toString()+"\n");
if (scUri == null) {
byteArrayOutputStream = new ByteArrayOutputStream();
objectOutput = new ObjectOutputStream(byteArrayOutputStream);
objectOutput.writeObject(pwm);
byte[] pwmBytes = byteArrayOutputStream.toByteArray();
this.storage.addPseudonymWithMetadata(username, pseudonymUri, pwmBytes);
} else {
if (pseudonym.isExclusive()) {
// TODO: hgk : find solution to specify if pseudonyms needs
// to be stored.
// System.out.println("For Soederhamn pilot, we do not store scope-exclusive pseudonyms. Returning without storing.");
String key = scUri + "::" + pseudonymUri;
// System.out.println("For Soederhamn pilot, we do not store scope-exclusive pseudonyms on Smartcard. Store in Memory Map with key : "
// + key + " : " + pwm.getPseudonym().getScope());
this.soderhamnTmpPseudonymMap.put(key, pwm);
return;
}
Smartcard sc = (Smartcard) this.cardStorage.getSmartcard(scUri);
pseudonymUri = this.escapeUri(pseudonymUri);
pseudonymUri = URI.create(PSEUDONYM_PREFIX + pseudonymUri.toString());
SmartcardStatusCode code =
sc.storePseudonym(this.cardStorage.getPin(scUri), pseudonymUri, pwm,
this.pseudonymSerializer);
// System.out.println("Result of storing pseudonym on card: " + code);
}
} catch (Exception ex) {
throw new CredentialManagerException(ex);
} finally {
// Close the streams.
StorageUtil.closeIgnoringException(objectOutput);
StorageUtil.closeIgnoringException(byteArrayOutputStream);
}
}
@Override
public void updateNonRevocationEvidence(String username) throws CredentialManagerException,
IssuerParametersNotInKeystoreException {
try {
for (URI credUid : this.listCredentials(username)) {
Credential cred = this.getCredential(username, credUid);
CredentialDescription credDesc = this.getCredentialDescription(username, credUid);
CredentialSpecification credSpec =
this.keyManager.getCredentialSpecification(credDesc.getCredentialSpecificationUID());
if (credSpec.isRevocable()) {
List<URI> revokedatts = new LinkedList<URI>();
revokedatts.add(new URI("http://abc4trust.eu/wp2/abcschemav1.0/revocationhandle"));
URI issuerParamUid = credDesc.getIssuerParametersUID();
IssuerParameters issuerParameters = this.keyManager.getIssuerParameters(issuerParamUid);
if (issuerParameters == null) {
throw new IssuerParametersNotInKeystoreException(
"Issuer parameters are not available in the Keystore");
}
URI revocationAuthorityParameters = issuerParameters.getRevocationParametersUID();
if (revocationAuthorityParameters == null) {
throw new CredentialManagerException(
"Revocation parameters not found in issuer parameters");
}
cred =
this.cryptoEngineUser.updateNonRevocationEvidence(username, cred,
revocationAuthorityParameters, revokedatts);
this.updateCredential(username, cred);
}
}
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
}
@Override
public boolean deleteCredential(String username, URI creduid) throws CredentialManagerException {
try {
Credential cred = this.getCredential(username, creduid);
if (cred != null) {
URI cardUid = cred.getCredentialDescription().getSecretReference();
BasicSmartcard sc = this.cardStorage.getSmartcards().get(cardUid);
if ((cardUid != null) && (sc != null) && !(sc instanceof SecretBasedSmartcard)) {
sc.deleteCredential(this.cardStorage.getPin(cardUid), creduid);
} else {
this.storage.deleteCredential(username, creduid);
}
return true;
}
return false;
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
}
@Override
public List<PseudonymWithMetadata> listPseudonyms(String username, String scope,
boolean onlyExclusive) throws CredentialManagerException {
try {
URI scUri = this.getSmartcardUri();
if (scUri == null) {
List<byte[]> listPseudonyms = this.storage.listPseudonyms(username);
List<PseudonymWithMetadata> ls =
new ArrayList<PseudonymWithMetadata>(listPseudonyms.size());
for (byte[] bytes : listPseudonyms) {
PseudonymWithMetadata pwm = this.parseBytesAsPseudonymWithMetaData(bytes);
Pseudonym pseudonym = pwm.getPseudonym();
if (pseudonym.getScope().equals(scope) && !(onlyExclusive && !pseudonym.isExclusive())) {
ls.add(pwm);
}
}
return ls;
} else {
List<PseudonymWithMetadata> ls = new ArrayList<PseudonymWithMetadata>();
Smartcard sc = (Smartcard) this.cardStorage.getSmartcard(scUri);
Map<URI, SmartcardBlob> blobs = sc.getBlobs(this.cardStorage.getPin(scUri));
for (URI uri : blobs.keySet()) {
String uriString = uri.toString();
if (uriString.startsWith(PSEUDONYM_PREFIX)) {
URI pseudonymUri = URI.create(uriString.substring(0, uriString.length() - 2));
PseudonymWithMetadata pwm =
sc.getPseudonym(this.cardStorage.getPin(scUri), pseudonymUri,
this.pseudonymSerializer);
Pseudonym pseudonym = pwm.getPseudonym();
if (pseudonym.getScope().equals(scope) && !(onlyExclusive && !pseudonym.isExclusive())) {
ls.add(pwm);
}
}
}
if (ls.size() == 0) {
// try the map:
for (PseudonymWithMetadata pwm : this.soderhamnTmpPseudonymMap.values()) {
if (pwm.getPseudonym().getScope().equals(scope)) {
ls.add(pwm);
}
}
}
return ls;
}
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
}
@Override
public PseudonymWithMetadata getPseudonym(String username, URI pseudonymUid)
throws CredentialManagerException, PseudonymIsNoInStorageException {
if (pseudonymUid == null) {
throw new CredentialManagerException("Pseudonym UID is null");
}
URI scUri = this.getSmartcardUri();
if (scUri == null) {
// storage based
byte[] tokenBytes = null;
try {
tokenBytes = this.storage.getPseudonymWithData(username, pseudonymUid);
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
if (tokenBytes == null) {
throw new PseudonymIsNoInStorageException("Pseudonym with UID: \"" + pseudonymUid
+ "\"is not in storage");
}
return this.parseBytesAsPseudonymWithMetaData(tokenBytes);
} else {
// smartcard based
try {
Smartcard sc = (Smartcard) this.cardStorage.getSmartcard(scUri);
int pin = this.cardStorage.getPin(scUri);
URI cardPseudonymUid = this.escapeUri(pseudonymUid);
cardPseudonymUid = URI.create(PSEUDONYM_PREFIX + cardPseudonymUid.toString());
return sc.getPseudonym(pin, cardPseudonymUid, this.pseudonymSerializer);
} catch (RuntimeException ex) {
// TODO : Fixup needed
// Exception from Smartcard/PseudonymSerializer could have been
// more specific - eg : PseudonymIsNoInStorageException
// -1 from inputstream means empty - returns exception like :
// Cannot unserialize this pseudonym: header was -1 expected
// header 68
if (ex.getMessage().toString().indexOf("header was -1") != -1
|| ex instanceof ArrayIndexOutOfBoundsException) {
String key = scUri + "::" + pseudonymUid;
PseudonymWithMetadata saved = this.soderhamnTmpPseudonymMap.get(key);
if (saved != null) {
// System.out.println("For Soderhamn Pilot. Found Pseudonym in Memory Map : "
// + key + " - Pwd : " + saved + " : " +
// saved.getPseudonym().getScope()) ;
return saved;
} else {
// System.out.println("For Soderhamn Pilot. Pseudonym NOT found in Memory Map : "
// + key );
}
throw new PseudonymIsNoInStorageException("Pseudonym is not stored on card!" + scUri);
} else {
throw new CredentialManagerException(ex);
}
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
}
}
@Override
public boolean deletePseudonym(String username, URI pseudonymUid)
throws CredentialManagerException {
try {
PseudonymWithMetadata pseudonym = this.getPseudonym(username, pseudonymUid);
if (pseudonym != null) {
URI scUri = this.getSmartcardUri();
if (scUri == null) {
this.storage.deletePseudonymWithMetadata(username, pseudonymUid);
return true;
} else {
Smartcard sc = (Smartcard) this.cardStorage.getSmartcard(scUri);
sc.deletePseudonym(this.cardStorage.getPin(scUri), pseudonymUid);
}
}
return false;
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
}
@Override
public void storeSecret(String username, Secret secret) throws CredentialManagerException {
ByteArrayOutputStream byteArrayOutputStream = null;
ObjectOutputStream objectOutput = null;
try {
byteArrayOutputStream = new ByteArrayOutputStream();
objectOutput = new ObjectOutputStream(byteArrayOutputStream);
objectOutput.writeObject(secret);
byte[] pwmBytes = byteArrayOutputStream.toByteArray();
URI secretUri = secret.getSecretDescription().getSecretUID();
this.sstorage.addSecret(username, secretUri, pwmBytes);
} catch (Exception ex) {
throw new CredentialManagerException(ex);
} finally {
// Close the streams.
StorageUtil.closeIgnoringException(objectOutput);
StorageUtil.closeIgnoringException(byteArrayOutputStream);
}
}
@Override
public List<SecretDescription> listSecrets(String username) throws CredentialManagerException {
try {
List<URI> listSecrets = this.sstorage.listSecrets(username);
List<SecretDescription> ls = new ArrayList<SecretDescription>(listSecrets.size());
for (URI uri : listSecrets) {
ls.add(this.getSecret(username, uri).getSecretDescription());
}
URI scUri = this.getSmartcardUri();
if (scUri != null) {
Smartcard sc = (Smartcard) this.cardStorage.getSmartcard(scUri);
SecretDescription secretDescr = new SecretDescription();
secretDescr.setDeviceBoundSecret(true);
secretDescr.setSecretUID(sc.getDeviceURI(this.cardStorage.getPin(scUri)));
FriendlyDescription fd = new FriendlyDescription();
fd.setLang("en");
fd.setValue("Placeholder for Smartcard secret");
secretDescr.getFriendlySecretDescription().add(fd);
ls.add(secretDescr);
}
return ls;
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
}
@Override
public boolean deleteSecret(String username, URI secuid) throws CredentialManagerException {
try {
Secret secret = this.getSecret(username, secuid);
if (secret != null) {
this.sstorage.deleteSecret(username, secuid);
return true;
}
return false;
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
}
@Override
public Secret getSecret(String username, URI secuid) throws CredentialManagerException,
SecretNotInStorageException {
if (secuid == null) {
throw new IllegalArgumentException("Secret UID is null");
}
ObjectInputStream objectInput = null;
ByteArrayInputStream byteArrayInputStream = null;
try {
byte[] secretBytes = this.sstorage.getSecret(username, secuid);
if (secretBytes == null) {
throw new SecretNotInStorageException("Secret is not in storage");
}
byteArrayInputStream = new ByteArrayInputStream(secretBytes);
objectInput = new ObjectInputStream(byteArrayInputStream);
Secret secret = (Secret) objectInput.readObject();
return secret;
} catch (SecretNotInStorageException ex) {
throw ex;
} catch (Exception ex) {
throw new CredentialManagerException(ex);
} finally {
// Close the streams.
StorageUtil.closeIgnoringException(objectInput);
StorageUtil.closeIgnoringException(byteArrayInputStream);
}
}
@Override
public void updateSecretDescription(String username, SecretDescription desc)
throws CredentialManagerException {
if (desc == null) {
throw new IllegalArgumentException("Secret Description is null");
}
try {
Secret sec = this.getSecret(username, desc.getSecretUID());
sec.setSecretDescription(desc);
this.sstorage.deleteSecret(username, desc.getSecretUID());
this.storeSecret(username, sec);
} catch (Exception ex) {
throw new CredentialManagerException(ex);
}
}
}