Newer
Older
import {
canTryPincode,
failPincodeAttempt,
getTimeLeftInLocalStorage,
makeid
} from "./appUtility";
import {
bufferToHexCodes,
stringToArrayBuffer,
isEqualBuffer
} from "pvutils";
import { ContentInfo, SignedData, Certificate } from "pkijs";
import {
fixNewLines,
getAttachment,
getAttachments,
getGlobalHeaderValue,
getHeaderValue,
parseMIME
} from "../helpers/mailparser";
import dataUriToBlob from "data-uri-to-blob";
import {
extractHtmlBodyFromString,
getFilenameFromHeaders,
SIGNATURE_CONTENT_TYPE
} from "./emailUtilities";
const libmime = require("libmime");
const pkijs = require("pkijs");
const asn1js = require("asn1js");
const pvutils = require("pvutils");
//*********************************************************************************
const CERTIFIATE_Version_1 = 0;
const CERTIFIATE_Version_3 = 2;
//these bit fields are reversed, WTF!
const KEY_USAGE_DigitalSignature = 0x80; //01;
const KEY_USAGE_NonRepudiation = 0x40; //02;
const KEY_USAGE_KeyEncipherment = 0x20; //04;
const KEY_USAGE_DataEncipherment = 0x10; //08;
const KEY_USAGE_KeyAgreement = 0x08; //10;
const KEY_USAGE_KeyCertSign = 0x04; //20;
const KEY_USAGE_CRLSign = 0x02; //40;
//const KEY_USAGE_EncipherOnly = 0x01;//80; // Not used for now. Must be used together with KEY_USAGE_KeyAgreement (maybe should be ORed as a constant directly?)
//const KEY_USAGE_DecipherOnly = 0x80;//0100; // If used, modify "KeyUsage" extension array buffer size and appropriate bit operators to accomodate for extra byte
const KEY_USAGE_LeafCertificate =
KEY_USAGE_DigitalSignature |
KEY_USAGE_NonRepudiation |
KEY_USAGE_KeyEncipherment |
KEY_USAGE_DataEncipherment;
const KEY_USAGE_CertificateAuthority =
KEY_USAGE_DigitalSignature | KEY_USAGE_KeyCertSign | KEY_USAGE_CRLSign;
const OID_EXT_KEY_USAGE_Any = "2.5.29.37.0";
const OID_ID_PKIX_ServerAuth = "1.3.6.1.5.5.7.3.1";
const OID_ID_PKIX_ClientAuth = "1.3.6.1.5.5.7.3.2";
const OID_ID_PKIX_CodeSigning = "1.3.6.1.5.5.7.3.3";
const OID_ID_PKIX_EmailProtection = "1.3.6.1.5.5.7.3.4";
const OID_ID_PKIX_TimeStamping = "1.3.6.1.5.5.7.3.8";
const OID_ID_PKIX_OCSPSigning = "1.3.6.1.5.5.7.3.9";
// const OID_EXT_KEY_USAGE_MS... = "1.3.6.1.4.1.311.10.3.1"; // Microsoft Certificate Trust List signing
// const OID_EXT_KEY_USAGE_MS... = "1.3.6.1.4.1.311.10.3.4"; // Microsoft Encrypted File System
const OID_PKCS7_Data = "1.2.840.113549.1.7.1";
const OID_PKCS7_SignedData = "1.2.840.113549.1.7.2";
const OID_PKCS7_EnvelopedData = "1.2.840.113549.1.7.3";
const OID_PKCS9_EmailAddress = "1.2.840.113549.1.9.1";
const OID_PKCS9_ContentType = "1.2.840.113549.1.9.3";
const OID_PKCS9_MessageDigest = "1.2.840.113549.1.9.4";
const OID_PKCS9_SigningTime = "1.2.840.113549.1.9.5";
const defaultAlgorithms = {
hashAlg: "SHA-256",
signAlg: "RSASSA-PKCS1-v1_5",
keyLength: 2048
};
const encryptionAlgorithm = {
name: "AES-CBC",
length: 128
};
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// Convert a hex string to a byte array
function hexStringToBytes(hex) {
for (let bytes = [], c = 0; c < hex.length; c += 2) {
bytes.push(parseInt(hex.substr(c, 2), 16));
}
return bytes;
}
export class CertificateData {
//**********************************************************************************
/**
* Constructor for SignedData class
* @param {pkijs.Certificate} [certificate]
* @param {Object} [parameters]
*/
constructor(parameters = {}) {
this.serialNumber = null; //string || ArrayBuffer || Uint8Array
this.keyPair = null; //{publicKey, privateKey}
this.signatureAlgorithm = null; //TODO remove from here and from dashboard
this.algorithms = {
hashAlg: null, //"SHA-256"
signAlg: null, //"RSASSA-PKCS1-v1_5"
keyLength: 0 //2048
};
this.issuer = null; //same as subject
this.subject = {
commonName: null, //string
country: null, //string
locality: null, //string
state: null, //string
organization: null, //string
organizationUnit: null, //string
email: null, //string
url: null //string
};
this.validity = {
notBefore: null, //new Date()
notAfter: null, //new Date()
validYears: 1 //int
};
this.isCA = false;
if (parameters) {
if (parameters instanceof Certificate) {
this.fromCertificate(parameters);
} else {
this.fromParameters(parameters);
}
}
}
fromCertificate(certificate) {
this.serialNumber = bufferToHexCodes(
certificate.serialNumber.valueBlock.valueHex
);
let signatureAlgorithm =
algomap[certificate.signatureAlgorithm.algorithmId];
if (typeof signatureAlgorithm === "undefined") {
signatureAlgorithm = certificate.signatureAlgorithm.algorithmId;
} else {
signatureAlgorithm = `${signatureAlgorithm}`;
}
this.signatureAlgorithm = signatureAlgorithm;
this.algorithms.signAlg = signatureAlgorithm;
this.issuer = {};
const issuer = certificate.issuer.typesAndValues;
for (const typeAndValue of issuer) {
let typeVal = rdnmap[typeAndValue.type];
if (typeof typeVal === "undefined") {
typeVal = typeAndValue.type;
}
const subjVal = typeAndValue.value.valueBlock.value;
this.issuer[typeVal] = subjVal;
}
const subject = certificate.subject.typesAndValues;
for (const typeAndValue of subject) {
let typeVal = rdnmap[typeAndValue.type];
if (typeof typeVal === "undefined") {
typeVal = typeAndValue.type;
}
const subjVal = typeAndValue.value.valueBlock.value;
this.subject[typeVal] = subjVal;
}
this.validity.notBefore = certificate.notBefore.value;
this.validity.notAfter = certificate.notAfter.value;
this.isCA = certificate.issuer.isEqual(certificate.subject);
}
fromParameters(parameters) {
if ("serialNumber" in parameters) {
this.serialNumber = parameters.serialNumber;
}
if ("keyPair" in parameters) {
this.keyPair = parameters.keyPair;
}
if ("signatureAlgorithm" in parameters) {
this.signatureAlgorithm = parameters.signatureAlgorithm;
}
if ("algorithms" in parameters) {
Loading
Loading full blame...