//* 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.smartcard; import java.net.URI; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import com.google.inject.Inject; /** * CardStorage * * Thread safety policy: Smartcards are created in either the thread running the * ABCE (the ABCE thread) or in the smart-card detector. And only used in the * ABCE thread. Smart-cards are added to the card storage by both threads thus * we guard the collection holding the smart-cards with a lock. But the * smart-card objects are not thread safe because they are only manipulated by * the ABCE thread. * * The CardStorage does not support client locking, because the lock is a * private internal lock object. * * @author Janus Dam Nielsen */ public class CardStorage { private final Map<URI, BasicSmartcard> cards; private final Map<URI, Integer> pins; private final Object lock; private final List<BasicSmartcard> closedCards; private final Map<BasicSmartcard, URI> smartcardToURI; @Inject public CardStorage() { super(); this.cards = new HashMap<URI, BasicSmartcard>(); this.pins = new HashMap<URI, Integer>(); this.lock = new Object(); this.closedCards = new LinkedList<BasicSmartcard>(); this.smartcardToURI = new HashMap<BasicSmartcard, URI>(); } public boolean addSmartcard(BasicSmartcard smartcard, int pin) { synchronized (this.lock) { URI cardUri = smartcard.getDeviceURI(pin); if (null == cardUri) { return false; } this.cards.put(cardUri, smartcard); this.pins.put(cardUri, pin); // this.smartcardToPin.put(smartcard, pin); this.smartcardToURI.put(smartcard, cardUri); } return true; } public boolean removeSmartcard(BasicSmartcard smartcard) { synchronized (this.lock) { if (this.smartcardToURI.containsKey(smartcard)) { return this.localRemoveSmartcard(smartcard); } if (this.closedCards.contains(smartcard)) { this.closedCards.remove(smartcard); return true; } return false; } } private boolean localRemoveSmartcard(BasicSmartcard smartcard/*, URI cardUri*/) { synchronized (this.lock) { URI cardUri = this.smartcardToURI.remove(smartcard); if(cardUri!=null) { this.cards.remove(cardUri); this.pins.remove(cardUri); } } return true; } public BasicSmartcard getSmartcard(URI smartcardUri) { synchronized (this.lock) { return this.cards.get(smartcardUri); } } public int getPin(URI smartcardUri) { synchronized (this.lock) { return this.pins.get(smartcardUri); } } public Map<URI, BasicSmartcard> getSmartcards() { synchronized (this.lock) { return Collections.unmodifiableMap(new HashMap<URI, BasicSmartcard>(this.cards)); } } public boolean addSmartcards(List<BasicSmartcard> smartcards, List<Integer> pins) { synchronized (this.lock) { boolean b = true; for (int inx = 0; inx < smartcards.size(); inx++) { BasicSmartcard sc = smartcards.get(inx); int pin = pins.get(inx); boolean addSmartcard = this.addSmartcard(sc, pin); if (addSmartcard) { if (this.closedCards.contains(sc)) { this.closedCards.remove(sc); } } b = b && addSmartcard; } return b; } } public void removeSmartcards(List<BasicSmartcard> smartcards, List<Integer> pins) { synchronized (this.lock) { for (int inx = 0; inx < smartcards.size(); inx++) { BasicSmartcard sc = smartcards.get(inx); this.localRemoveSmartcard(sc/*, pin*/); } } } public List<BasicSmartcard> getClosedSmartcards() { synchronized (this.lock) { return this.closedCards; } } public void addClosedSmartcards(List<Smartcard> closedCards) { synchronized (this.lock) { this.closedCards.addAll(closedCards); } } public boolean unlockClosedSmartcards(List<BasicSmartcard> closedCards, List<Integer> pins) { synchronized (this.lock) { return this.addSmartcards(closedCards, pins); } } }