Skip to content
Snippets Groups Projects
signingUtilities.js 35.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • 
    function capitalizeFirstLetter(string) {
    
    Alexey Lunin's avatar
    Alexey Lunin committed
      if (string === "id") {
        return "ID";
    
    Alexey Lunin's avatar
    Alexey Lunin committed
      if (string === "mime") {
    
        return "MIME";
      }
    
      return string.charAt(0).toUpperCase() + string.slice(1);
    }
    
    function capitalizeHeader(string) {
      let result = "";
      const tokens = string.split("-");
      for (let i = 0; i < tokens.length; i++) {
        result += capitalizeFirstLetter(tokens[i]);
        if (i !== tokens.length - 1) {
          result += "-";
        }
      }
    
      return result;
    }
    
    function makeBoundary() {
      let len = 20 + Math.random() * 20;
    
    Alexey Lunin's avatar
    Alexey Lunin committed
      return "W0RyLiBEYW15YW4gTWl0ZXZd--" + makeid(len);
    
    }
    
    export const parseCertificates = signatureBase64 => {
      try {
        const certificateDecoded = atob(signatureBase64);
        const buffer = stringToArrayBuffer(certificateDecoded);
        const asn1 = fromBER(buffer);
    
        const contentInfo = new ContentInfo({ schema: asn1.result });
        const signedData = new SignedData({ schema: contentInfo.content });
    
        return signedData.certificates.map((certificate, index) => {
          const certificateData = { issuer: {}, subject: {}, validity: {} };
          const serialNumber = bufferToHexCodes(
            certificate.serialNumber.valueBlock.valueHex
          );
          const issuer = certificate.issuer.typesAndValues;
          const subject = certificate.subject.typesAndValues;
    
          const notAfter = certificate.notAfter.value;
          const notBefore = certificate.notBefore.value;
    
          let signatureAlgorithm =
            algomap[certificate.signatureAlgorithm.algorithmId];
          if (typeof signatureAlgorithm === "undefined") {
            signatureAlgorithm = certificate.signatureAlgorithm.algorithmId;
          } else {
            signatureAlgorithm = `${signatureAlgorithm}`;
          }
    
          for (const typeAndValue of issuer) {
            let typeVal = rdnmap[typeAndValue.type];
            if (typeof typeVal === "undefined") {
              typeVal = typeAndValue.type;
            }
            const subjVal = typeAndValue.value.valueBlock.value;
            certificateData.issuer[typeVal] = subjVal;
          }
    
          for (const typeAndValue of subject) {
            let typeVal = rdnmap[typeAndValue.type];
            if (typeof typeVal === "undefined") {
              typeVal = typeAndValue.type;
            }
            const subjVal = typeAndValue.value.valueBlock.value;
            certificateData.subject[typeVal] = subjVal;
          }
    
          certificateData.signatureAlgorithm = signatureAlgorithm;
          certificateData.serialNumber = serialNumber;
          certificateData.validity = {
            notAfter,
            notBefore
          };
    
          return certificateData;
        });
      } catch (e) {
        console.error("Error parsing certificate", e);
      }
    };
    
    export const getCertificateChain = signatureBase64 => {
      const certificateChain = [];
    
      try {
        const certificates = parseCertificates(signatureBase64);
    
        // Add first certificate in the chain
        certificateChain.push(certificates[0]);
    
        // Go through all certificates to build a chain from first certificate to the root
        certificates.forEach(certificate => {
    
    Alexey Lunin's avatar
    Alexey Lunin committed
          if (
            certificateChain[0].issuer.commonName === certificate.subject.commonName
          ) {
    
            certificateChain.unshift(certificate);
          }
        });
      } catch (e) {
        console.warn("Error getting certificate data", e);
      }
    
      return certificateChain;
    };