UNPKG

undersign

Version:

Create eIDAS compatible XAdES digital signatures with certificate OCSP responses and timestamps. Works with the Estonian Id-card and Mobile-Id to create BDOCs, but isn't limited to Estonia.

75 lines (61 loc) 2.21 kB
var Zip = require("yazl").ZipFile var ReadableStream = require("stream").Readable var ManifestXml = require("./manifest_xml") var Xades = require("../xades") var concat = Array.prototype.concat.bind(Array.prototype) var slurp = require("./stream").slurp var MIMETYPE_BUFFER = Buffer.from("application/vnd.etsi.asic-e+zip") module.exports = Asic function Asic() { this.zip = new Zip // As per the ASiC specification v1.1.1 // (https://www.etsi.org/deliver/etsi_en/319100_319199/31916201/01.01.01_60/en_31916201v010101p.pdf), mimetype needs to be both first and uncompressed. this.zip.addBuffer(MIMETYPE_BUFFER, "mimetype", {compress: false}) this.files = [] this.signatures = 0 this.ended = false } Asic.prototype.type = "application/vnd.etsi.asic-e+zip" Asic.prototype.add = function(path, data, type) { add(this.zip, path, data) this.files.push({path: path, type: type}) } Asic.prototype.addSignature = function(signature) { if (signature instanceof Xades) signature = String(signature) add(this.zip, `META-INF/signatures-${++this.signatures}.xml`, signature) } Asic.prototype.toStream = function() { return this.zip.outputStream } Asic.prototype.pipe = function(to, opts) { return this.toStream().pipe(to, opts) } Asic.prototype.unpipe = function(to) { return this.toStream.unpipe(to) } Asic.prototype.end = function() { if (this.ended) return add(this.zip, "META-INF/manifest.xml", serializeManifest(this.files)) this.zip.end() this.ended = true } Asic.prototype.toBuffer = function() { this.end() return slurp(this.toStream()) } function serializeManifest(files) { return ManifestXml.stringify({ "m$manifest": { "m$file-entry": concat({ "m$media-type": "application/vnd.etsi.asic-e+zip", "m$full-path": "/" }, files.map((file) => ({ // TODO: Are file full paths with a leading slash or not? "m$media-type": String(file.type), "m$full-path": file.path }))) } }) } function add(zip, path, data) { if (typeof data == "string") data = Buffer.from(data) if (data instanceof Buffer) zip.addBuffer(data, path) else if (data instanceof ReadableStream) zip.addReadStream(data, path) else throw new TypeError("Unsupported Asic data: " + data) }