EAC2CVRequestGenerator.js
Summary
Implementation of Simple CV request generator based on
TR-03110 "Advanced Security Mechanisms for Machine Readable Travel Documents", Version 2.0
load("tools/eccutils.js");
if (typeof(__ScriptingServer) == "undefined") {
load("cvc.js");
}
function EAC2CVRequestGenerator(crypto) {
this.crypto = crypto;
}
EAC2CVRequestGenerator.encodeUncompressedECPoint = function(x, y) {
bb = new ByteBuffer();
bb.append(new ByteString("04", HEX));
bb.append(new ByteString(x, HEX));
bb.append(new ByteString(y, HEX));
return bb.toByteString();
}
EAC2CVRequestGenerator.stripLeadingZeros = function(value) {
var i = 0;
for (; (i < value.length) && (value.byteAt(i) == 0); i++);
return value.right(value.length - i);
}
EAC2CVRequestGenerator.prototype.setPublicKey = function(publicKey) {
this.publicKey = publicKey;
}
EAC2CVRequestGenerator.prototype.setCHR = function(chr) {
if (chr instanceof ByteString) {
this.CHR = chr;
} else if (chr instanceof PublicKeyReference) {
this.CHR = chr.getBytes();
} else {
this.CHR = new ByteString(chr.toString(), ASCII);
}
}
EAC2CVRequestGenerator.prototype.reset = function() {
}
EAC2CVRequestGenerator.prototype.setProfileIdentifier = function(profileID) {
this.profileIdentifier = profileID;
}
EAC2CVRequestGenerator.prototype.setCAR = function(car) {
if (car instanceof ByteString) {
this.CAR = car;
} else if (car instanceof PublicKeyReference) {
this.CAR = car.getBytes();
} else {
this.CAR = new ByteString(car.toString(), ASCII);
}
}
EAC2CVRequestGenerator.prototype.setExtensions = function(extensions) {
this.extensions = extensions;
}
EAC2CVRequestGenerator.prototype.setTAAlgorithmIdentifier = function(oid) {
this.taOID = oid;
}
EAC2CVRequestGenerator.prototype.getCAR = function() {
var t = new ASN1("Certification Authority Reference", 0x42, this.CAR);
return t;
}
EAC2CVRequestGenerator.prototype.getCHR = function() {
var t = new ASN1("Certification Holder Reference", 0x5F20, this.CHR);
return t;
}
EAC2CVRequestGenerator.prototype.getPublicKey = function() {
var t = new ASN1("Public Key", 0x7F49);
t.add(new ASN1("Object Identifier", 0x06, this.taOID));
if (typeof(this.publicKey.getComponent(Key.ECC_P)) != "undefined") {
t.add(new ASN1("Prime Modulus", 0x81, this.publicKey.getComponent(Key.ECC_P)));
t.add(new ASN1("First coefficient a", 0x82, this.publicKey.getComponent(Key.ECC_A)));
t.add(new ASN1("Second coefficient b", 0x83, this.publicKey.getComponent(Key.ECC_B)));
t.add(new ASN1("Base Point G", 0x84, EAC2CVRequestGenerator.encodeUncompressedECPoint(this.publicKey.getComponent(Key.ECC_GX), this.publicKey.getComponent(Key.ECC_GY))));
t.add(new ASN1("Order of the base point", 0x85, this.publicKey.getComponent(Key.ECC_N)));
t.add(new ASN1("Public Point y", 0x86, EAC2CVRequestGenerator.encodeUncompressedECPoint(this.publicKey.getComponent(Key.ECC_QX), this.publicKey.getComponent(Key.ECC_QY))));
t.add(new ASN1("Cofactor f", 0x87, EAC2CVRequestGenerator.stripLeadingZeros(this.publicKey.getComponent(Key.ECC_H))));
} else {
t.add(new ASN1("Composite Modulus", 0x81, this.publicKey.getComponent(Key.MODULUS)));
t.add(new ASN1("Public Exponent", 0x82, this.publicKey.getComponent(Key.EXPONENT)));
}
return t;
}
EAC2CVRequestGenerator.prototype.getProfileIdentifier = function() {
var bb = new ByteBuffer();
bb.append(this.profileIdentifier);
var t = new ASN1("Certificate Profile Identifier", 0x5F29, bb.toByteString());
return t;
}
EAC2CVRequestGenerator.prototype.getExtensions = function() {
var t = new ASN1("Certificate Extensions", 0x7F49);
for (var i = 0; i < this.extensions.length; i++)
t.add(this.extensions[i]);
return t;
}
EAC2CVRequestGenerator.prototype.getCertificateBody = function() {
var t = new ASN1("Certificate Body", 0x7F4E);
t.add(this.getProfileIdentifier());
if (this.CAR) {
t.add(this.getCAR());
}
t.add(this.getPublicKey());
t.add(this.getCHR());
if (this.extensions) {
t.add(this.getExtensions());
}
return t;
}
EAC2CVRequestGenerator.prototype.generateCVRequest = function(privateKey) {
var request = new ASN1("CV Certificate", 0x7F21);
var body = this.getCertificateBody();
request.add(body);
var mech = CVC.getSignatureMech(this.taOID);
var signature = this.crypto.sign(privateKey, mech, body.getBytes());
if (CVC.isECDSA(this.taOID)) {
var keylen = privateKey.getSize() >> 3;
var signatureValue = new ASN1("Signature", 0x5F37, ECCUtils.unwrapSignature(signature, keylen));
} else {
var signatureValue = new ASN1("Signature", 0x5F37, signature);
}
request.add(signatureValue);
return request;
}
EAC2CVRequestGenerator.signAuthenticatedCVRequest = function(crypto, request, authenticationKey, authCHR, outertaOID) {
var authRequest = new ASN1("Authentication", 0x67);
var chr = new ASN1("Certification Authority Reference", 0x42, authCHR.getBytes());
var signatureInput = request.getBytes().concat(chr.getBytes());
var mech = CVC.getSignatureMech(outertaOID);
var signature = crypto.sign(authenticationKey, mech, signatureInput);
if (CVC.isECDSA(outertaOID)) {
var keylen = authenticationKey.getSize() >> 3;
var signatureValue = new ASN1("Signature", 0x5F37, ECCUtils.unwrapSignature(signature, keylen));
} else {
var signatureValue = new ASN1("Signature", 0x5F37, signature);
}
authRequest.add(request);
authRequest.add(chr);
authRequest.add(signatureValue);
return authRequest;
}
EAC2CVRequestGenerator.prototype.generateAuthenticatedCVRequest = function(requestKey, authenticationKey, authCHR, outertaOID) {
var request = this.generateCVRequest(requestKey);
if (typeof(outertaOID) == "undefined") {
outertaOID = this.taOID;
}
return EAC2CVRequestGenerator.signAuthenticatedCVRequest(this.crypto, request, authenticationKey, authCHR, outertaOID);
}
Documentation generated by
JSDoc on Tue Sep 3 22:29:38 2013