use of org.openecard.crypto.common.sal.did.CryptoMarkerType in project open-ecard by ecsec.
the class Signer method sign.
public byte[] sign(byte[] data) throws NoSuchDid, WSHelper.WSException, SecurityConditionUnsatisfiable, ParameterInvalid, SlotHandleInvalid, PinBlocked {
Semaphore s = getLock(handle.getIFDName());
boolean acquired = false;
try {
s.acquire();
acquired = true;
// get crypto dids
DidInfos didInfos = tokenCache.getInfo(pin, handle);
DidInfo didInfo = didInfos.getDidInfo(didName);
didInfo.connectApplication();
didInfo.authenticateMissing();
CryptoMarkerType cryptoMarker = didInfo.getGenericCryptoMarker();
String algUri = cryptoMarker.getAlgorithmInfo().getAlgorithmIdentifier().getAlgorithm();
try {
SignatureAlgorithms alg = SignatureAlgorithms.fromAlgId(algUri);
// calculate hash if needed
byte[] digest = data;
if (alg.getHashAlg() != null && (cryptoMarker.getHashGenerationInfo() == null || cryptoMarker.getHashGenerationInfo() == HashGenerationInfoType.NOT_ON_CARD)) {
digest = didInfo.hash(digest);
}
// wrap hash in DigestInfo if needed
if (alg == SignatureAlgorithms.CKM_RSA_PKCS) {
try {
ASN1ObjectIdentifier digestOid = getHashAlgOid(data);
DigestInfo di = new DigestInfo(new AlgorithmIdentifier(digestOid, DERNull.INSTANCE), digest);
byte[] sigMsg = di.getEncoded(ASN1Encoding.DER);
digest = sigMsg;
} catch (IOException ex) {
String msg = "Error encoding DigestInfo object.";
Result r = WSHelper.makeResultError(ECardConstants.Minor.App.INT_ERROR, msg);
throw WSHelper.createException(r);
} catch (InvalidParameterException ex) {
String msg = "Hash algorithm could not be determined for the given hash.";
Result r = WSHelper.makeResultError(ECardConstants.Minor.App.INCORRECT_PARM, msg);
throw WSHelper.createException(r);
}
}
byte[] signature = didInfo.sign(digest);
return signature;
} catch (UnsupportedAlgorithmException ex) {
String msg = String.format("DID uses unsupported algorithm %s.", algUri);
throw WSHelper.createException(WSHelper.makeResultError(ECardConstants.Minor.App.INT_ERROR, msg));
}
} catch (WSHelper.WSException ex) {
String minor = StringUtils.nullToEmpty(ex.getResultMinor());
switch(minor) {
case ECardConstants.Minor.App.INCORRECT_PARM:
throw new ParameterInvalid(ex.getMessage(), ex);
case ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE:
throw new SlotHandleInvalid(ex.getMessage(), ex);
case ECardConstants.Minor.IFD.PASSWORD_BLOCKED:
case ECardConstants.Minor.IFD.PASSWORD_SUSPENDED:
case ECardConstants.Minor.IFD.PASSWORD_DEACTIVATED:
throw new PinBlocked(ex.getMessage(), ex);
case ECardConstants.Minor.SAL.SECURITY_CONDITION_NOT_SATISFIED:
throw new SecurityConditionUnsatisfiable(ex.getMessage(), ex);
case ECardConstants.Minor.IFD.CANCELLATION_BY_USER:
case ECardConstants.Minor.SAL.CANCELLATION_BY_USER:
throw new ThreadTerminateException("Signature generation cancelled.", ex);
default:
throw ex;
}
} catch (InvocationTargetExceptionUnchecked ex) {
if (ex.getCause() instanceof InterruptedException || ex.getCause() instanceof ThreadTerminateException) {
throw new ThreadTerminateException("Signature creation interrupted.");
} else {
String msg = ex.getCause().getMessage();
throw WSHelper.createException(WSHelper.makeResultError(ECardConstants.Minor.App.INT_ERROR, msg));
}
} catch (InterruptedException ex) {
throw new ThreadTerminateException("Signature creation interrupted.");
} finally {
tokenCache.clearPins();
if (acquired) {
s.release();
}
}
}
use of org.openecard.crypto.common.sal.did.CryptoMarkerType in project open-ecard by ecsec.
the class SignStep method perform.
@Override
public SignResponse perform(Sign sign, Map<String, Object> internalData) {
SignResponse response = WSHelper.makeResponse(SignResponse.class, WSHelper.makeResultOK());
try {
ConnectionHandleType connectionHandle = SALUtils.getConnectionHandle(sign);
String didName = SALUtils.getDIDName(sign);
CardStateEntry cardStateEntry = SALUtils.getCardStateEntry(internalData, connectionHandle);
DIDStructureType didStructure = SALUtils.getDIDStructure(sign, didName, cardStateEntry, connectionHandle);
CryptoMarkerType cryptoMarker = new CryptoMarkerType(didStructure.getDIDMarker());
byte[] slotHandle = connectionHandle.getSlotHandle();
byte[] applicationID = connectionHandle.getCardApplication();
Assert.securityConditionDID(cardStateEntry, applicationID, didName, CryptographicServiceActionName.SIGN);
byte[] message = sign.getMessage();
byte[] keyReference = cryptoMarker.getCryptoKeyInfo().getKeyRef().getKeyRef();
byte[] algorithmIdentifier = cryptoMarker.getAlgorithmInfo().getCardAlgRef();
byte[] hashRef = cryptoMarker.getAlgorithmInfo().getHashAlgRef();
HashGenerationInfoType hashInfo = cryptoMarker.getHashGenerationInfo();
if (didStructure.getDIDScope() == DIDScopeType.LOCAL) {
keyReference[0] = (byte) (0x80 | keyReference[0]);
}
if (cryptoMarker.getSignatureGenerationInfo() != null) {
response = performSignature(cryptoMarker, keyReference, algorithmIdentifier, message, slotHandle, hashRef, hashInfo);
} else {
// assuming that legacySignatureInformation exists
BaseTemplateContext templateContext = new BaseTemplateContext();
templateContext.put(HASH_TO_SIGN, message);
templateContext.put(KEY_REFERENCE, keyReference);
templateContext.put(ALGORITHM_IDENTIFIER, algorithmIdentifier);
templateContext.put(HASHALGORITHM_REFERENCE, hashRef);
response = performLegacySignature(cryptoMarker, connectionHandle, templateContext);
}
} catch (ECardException e) {
response.setResult(e.getResult());
} catch (Exception e) {
LOG.warn(e.getMessage(), e);
response.setResult(WSHelper.makeResult(e));
}
return response;
}
use of org.openecard.crypto.common.sal.did.CryptoMarkerType in project open-ecard by ecsec.
the class VerifySignatureStep method perform.
@Override
public VerifySignatureResponse perform(VerifySignature request, Map<String, Object> internalData) {
VerifySignatureResponse response = WSHelper.makeResponse(VerifySignatureResponse.class, WSHelper.makeResultOK());
try {
ConnectionHandleType connectionHandle = SALUtils.getConnectionHandle(request);
CardStateEntry cardStateEntry = SALUtils.getCardStateEntry(internalData, connectionHandle);
String didName = SALUtils.getDIDName(request);
DIDStructureType didStructure = SALUtils.getDIDStructure(request, didName, cardStateEntry, connectionHandle);
// required
byte[] signature = request.getSignature();
// optional
byte[] message = request.getMessage();
CryptoMarkerType cryptoMarker = new CryptoMarkerType(didStructure.getDIDMarker());
String dataSetNameCertificate = cryptoMarker.getCertificateRefs().get(0).getDataSetName();
String algorithmIdentifier = cryptoMarker.getAlgorithmInfo().getAlgorithmIdentifier().getAlgorithm();
DSIRead dsiRead = new DSIRead();
dsiRead.setConnectionHandle(connectionHandle);
dsiRead.setDSIName(dataSetNameCertificate);
DSIReadResponse dsiReadResponse = (DSIReadResponse) dispatcher.safeDeliver(dsiRead);
WSHelper.checkResult(dsiReadResponse);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
Certificate cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(dsiReadResponse.getDSIContent()));
Signature signatureAlgorithm;
if (algorithmIdentifier.equals(GenericCryptoUris.RSA_ENCRYPTION)) {
signatureAlgorithm = Signature.getInstance("RSA", new BouncyCastleProvider());
} else if (algorithmIdentifier.equals(GenericCryptoUris.RSASSA_PSS_SHA256)) {
signatureAlgorithm = Signature.getInstance("RAWRSASSA-PSS", new BouncyCastleProvider());
signatureAlgorithm.setParameter(new PSSParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), 32, 1));
} else if (algorithmIdentifier.equals(GenericCryptoUris.sigS_ISO9796_2)) {
return WSHelper.makeResponse(VerifySignatureResponse.class, WSHelper.makeResultUnknownError(algorithmIdentifier + " Not supported yet."));
} else if (algorithmIdentifier.equals(GenericCryptoUris.sigS_ISO9796_2rnd)) {
return WSHelper.makeResponse(VerifySignatureResponse.class, WSHelper.makeResultUnknownError(algorithmIdentifier + " Not supported yet."));
} else {
throw new IncorrectParameterException("Unknown signature algorithm.");
}
signatureAlgorithm.initVerify(cert);
if (message != null) {
signatureAlgorithm.update(message);
}
if (!signatureAlgorithm.verify(signature)) {
throw new InvalidSignatureException();
}
} catch (ECardException e) {
LOG.error(e.getMessage(), e);
response.setResult(e.getResult());
} catch (Exception e) {
response.setResult(WSHelper.makeResult(e));
}
return response;
}
use of org.openecard.crypto.common.sal.did.CryptoMarkerType in project open-ecard by ecsec.
the class SmartCardSignerCredential method genSig.
private byte[] genSig(SignatureAndHashAlgorithm algorithm, byte[] sigData, boolean isRaw) throws IOException {
SignatureAlgorithms didAlg = getDidAlgorithm();
LOG.debug("Using DID with algorithm={}.", didAlg.getJcaAlg());
if (algorithm != null) {
String reqAlgStr = String.format("%s-%s", SignatureAlgorithm.getText(algorithm.getSignature()), HashAlgorithm.getText(algorithm.getHash()));
LOG.debug("Performing TLS 1.2 signature for algorithm={}.", reqAlgStr);
if (isRaw && isRawRSA(didAlg)) {
// TLS >= 1.2 needs a PKCS#1 v1.5 signature and no raw RSA signature
ASN1ObjectIdentifier hashAlgId = TlsUtils.getOIDForHashAlgorithm(algorithm.getHash());
DigestInfo digestInfo = new DigestInfo(new AlgorithmIdentifier(hashAlgId, DERNull.INSTANCE), sigData);
sigData = digestInfo.getEncoded(ASN1Encoding.DER);
LOG.debug("Signing DigestInfo with algorithm={}.", hashAlgId);
}
} else {
LOG.debug("Performing pre-TLS 1.2 signature.");
}
try {
if (isRaw) {
LOG.debug("Raw Signature of data={}.", ByteUtils.toHexString(sigData));
} else {
LOG.debug("Hashed Signature of data blob.");
CryptoMarkerType cryptoMarker = did.getGenericCryptoMarker();
if (didAlg.getHashAlg() != null && (cryptoMarker.getHashGenerationInfo() == null || cryptoMarker.getHashGenerationInfo() == HashGenerationInfoType.NOT_ON_CARD)) {
sigData = did.hash(sigData);
}
}
did.authenticateMissing();
byte[] signature = did.sign(sigData);
return signature;
} catch (WSHelper.WSException ex) {
String msg = "Failed to create signature because of an unknown error.";
LOG.warn(msg, ex);
throw new IOException(msg, ex);
} catch (SecurityConditionUnsatisfiable ex) {
String msg = "Access to the signature DID could not be obtained.";
LOG.warn(msg, ex);
throw new IOException(msg, ex);
} catch (NoSuchDid ex) {
String msg = "Signing DID not available anymore.";
LOG.warn(msg, ex);
throw new IOException(msg, ex);
}
}
use of org.openecard.crypto.common.sal.did.CryptoMarkerType in project open-ecard by ecsec.
the class TinySAL method didList.
/**
* The DIDList function returns a list of the existing DIDs in the card application addressed by the
* ConnectionHandle or the ApplicationIdentifier element within the Filter.
* See BSI-TR-03112-4, version 1.1.2, section 3.6.1.
*
* @param request DIDList
* @return DIDListResponse
*/
@Publish
@Override
public DIDListResponse didList(DIDList request) {
DIDListResponse response = WSHelper.makeResponse(DIDListResponse.class, WSHelper.makeResultOK());
try {
ConnectionHandleType connectionHandle = SALUtils.getConnectionHandle(request);
byte[] appId = connectionHandle.getCardApplication();
CardStateEntry cardStateEntry = SALUtils.getCardStateEntry(states, connectionHandle, false);
Assert.securityConditionApplication(cardStateEntry, appId, DifferentialIdentityServiceActionName.DID_LIST);
byte[] applicationIDFilter = null;
String objectIDFilter = null;
String applicationFunctionFilter = null;
DIDQualifierType didQualifier = request.getFilter();
if (didQualifier != null) {
applicationIDFilter = didQualifier.getApplicationIdentifier();
objectIDFilter = didQualifier.getObjectIdentifier();
applicationFunctionFilter = didQualifier.getApplicationFunction();
}
/*
* Filter by ApplicationIdentifier.
* [TR-03112-4] Allows specifying an application identifier. If this element is present all
* DIDs within the specified card application are returned no matter which card application
* is currently selected.
*/
CardApplicationWrapper cardApplication;
if (applicationIDFilter != null) {
cardApplication = cardStateEntry.getInfo().getCardApplication(applicationIDFilter);
Assert.assertIncorrectParameter(cardApplication, "The given CardApplication cannot be found.");
} else {
cardApplication = cardStateEntry.getCurrentCardApplication();
}
List<DIDInfoType> didInfos = new ArrayList<>(cardApplication.getDIDInfoList());
/*
* Filter by ObjectIdentifier.
* [TR-03112-4] Allows specifying a protocol OID (cf. [TR-03112-7]) such that only DIDs
* which support a given protocol are listed.
*/
if (objectIDFilter != null) {
Iterator<DIDInfoType> it = didInfos.iterator();
while (it.hasNext()) {
DIDInfoType next = it.next();
if (!next.getDifferentialIdentity().getDIDProtocol().equals(objectIDFilter)) {
it.remove();
}
}
}
/*
* Filter by ApplicationFunction.
* [TR-03112-4] Allows filtering for DIDs, which support a specific cryptographic operation.
* The bit string is coded as the SupportedOperations-element in [ISO7816-15].
*/
if (applicationFunctionFilter != null) {
Iterator<DIDInfoType> it = didInfos.iterator();
while (it.hasNext()) {
DIDInfoType next = it.next();
if (next.getDifferentialIdentity().getDIDMarker().getCryptoMarker() == null) {
it.remove();
} else {
iso.std.iso_iec._24727.tech.schema.CryptoMarkerType rawMarker;
rawMarker = next.getDifferentialIdentity().getDIDMarker().getCryptoMarker();
CryptoMarkerType cryptoMarker = new CryptoMarkerType(rawMarker);
AlgorithmInfoType algInfo = cryptoMarker.getAlgorithmInfo();
if (!algInfo.getSupportedOperations().contains(applicationFunctionFilter)) {
it.remove();
}
}
}
}
DIDNameListType didNameList = new DIDNameListType();
for (DIDInfoType didInfo : didInfos) {
didNameList.getDIDName().add(didInfo.getDifferentialIdentity().getDIDName());
}
response.setDIDNameList(didNameList);
} catch (ECardException e) {
response.setResult(e.getResult());
} catch (Exception e) {
LOG.error(e.getMessage(), e);
throwThreadKillException(e);
response.setResult(WSHelper.makeResult(e));
}
return response;
}
Aggregations