EACKeyStore.js
Summary
Keystore class for EAC keys and certificates
SmartCardHSM = require("scsh/sc-hsm/SmartCardHSM").SmartCardHSM;
CVC = require("scsh/eac/CVC").CVC;
PublicKeyReference = require('scsh/eac/PublicKeyReference').PublicKeyReference;
function EACKeyStore(sc, certstore, path) {
this.sc = sc;
this.certstore = certstore;
this.path = path;
}
exports.EACKeyStore = EACKeyStore;
EACKeyStore.prototype.getCertificateStore = function() {
return this.certstore;
}
EACKeyStore.prototype.getC_DevAut = function() {
var rsp = sc.readBinary(SmartCardHSM.C_DevAut);
return new CVC(rsp);
}
EACKeyStore.prototype.getCurrentCertificateFID = function() {
var i = 0;
while (i <= 1) {
try {
var fid = ByteString.valueOf(0xC001 + i);
var cvcbin = sc.readBinary(fid);
var cvc = new CVC(cvcbin);
return fid;
}
catch(e) {
}
i++;
}
return null;
}
EACKeyStore.prototype.getCertificateByFID = function(fid) {
try {
var cvcbin = sc.readBinary(fid);
var cvc = new CVC(cvcbin);
return cvc;
}
catch(e) {
GPSystem.trace("No certificate found in " + fid.toString(HEX) + " or certificate invalid");
}
return null;
}
EACKeyStore.prototype.getNextSequence = function() {
var nextseq = 1;
var fid = new ByteString("C100", HEX);
try {
var seqno = sc.readBinary(fid);
var nextseq = seqno.toUnsigned() + 1;
}
catch(e) {
GPSystem.trace("No sequence no found in " + fid.toString(HEX));
}
sc.updateBinary(fid, 0, ByteString.valueOf(nextseq), 4);
var seq = "" + nextseq;
seq = "00000".substr(0, 5 - seq.length) + seq;
return seq;
}
EACKeyStore.prototype.generateRequest = function(forceInitial) {
var c_devaut = this.getC_DevAut();
var chr = c_devaut.getCHR();
var outerCAR;
var initialRequest = false;
var fid = this.getCurrentCertificateFID();
if (fid && (!forceInitial)) {
var signkid = fid.byteAt(1);
var keyid = 3 - signkid;
var currentcvc = this.getCertificateByFID(fid);
outerCAR = currentcvc.getCHR();
} else {
var keyid = 1;
var signkid = 0;
initialRequest = true;
if (fid) {
if (this.sc.hasFile(fid)) {
this.sc.deleteFile(fid);
}
}
}
var car = this.certstore.getCurrentCHR(this.path);
if (car == null) {
print("Can't locate current DVCA certificate");
return;
}
var dvca = this.certstore.getCertificate(this.path, car);
var chr = new PublicKeyReference(chr.getHolder() + this.getNextSequence());
var algo = dvca.getPublicKeyOID();
if (CVC.isECDSA(algo)) {
var dp = this.certstore.getDomainParameter(this.path, car);
var cdata = SmartCardHSM.buildGAKPwithECC(car, algo, chr, dp, outerCAR);
} else {
var cdata = SmartCardHSM.buildGAKPwithRSA(car, algo, chr, 1024, outerCAR);
}
print("Generating new key and certificate signing request...");
var fid = ByteString.valueOf((SmartCardHSM.KEYPREFIX << 8) + keyid);
this.sc.deleteFile(fid);
var req = this.sc.generateAsymmetricKeyPair(keyid, signkid, cdata);
if (initialRequest) {
var a = new ASN1(req);
req = a.get(0);
}
return new CVC(req);
}
EACKeyStore.prototype.updateCardCertificate = function() {
var c_devaut = this.getC_DevAut();
var chr = c_devaut.getCHR();
var path = this.path + "/" + chr.getHolder();
var chr = this.certstore.getCurrentCHR(path);
var cvc = this.certstore.getCertificate(path, chr);
var fid = this.getCurrentCertificateFID();
if (!fid) {
var newfid = new ByteString("C001", HEX);
} else {
var newfid = ByteString.valueOf(0xC000 + 3 - fid.byteAt(1));
}
this.sc.updateBinary(newfid, 0, cvc.getBytes());
print("Certificate written to EF " + newfid.toString(HEX));
if (fid) {
this.sc.deleteFile(fid);
print("EF " + fid.toString(HEX) + " deleted");
}
}
Documentation generated by
JSDoc on Sat Feb 24 15:17:19 2024