• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PeculiarVentures / x509 / 17560650653

08 Sep 2025 06:39PM UTC coverage: 89.864% (-0.5%) from 90.404%
17560650653

push

github

web-flow
Merge pull request #107 from PeculiarVentures/low-speed

ASN structure reading optimizations

871 of 1014 branches covered (85.9%)

Branch coverage included in aggregate %.

344 of 386 new or added lines in 22 files covered. (89.12%)

7 existing lines in 5 files now uncovered.

3021 of 3317 relevant lines covered (91.08%)

47.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.88
/src/rsa_algorithm.ts
1
import * as asn1Rsa from "@peculiar/asn1-rsa";
2✔
2
import { AsnConvert } from "@peculiar/asn1-schema";
2✔
3
import { AlgorithmIdentifier } from "@peculiar/asn1-x509";
2✔
4
import { container, injectable } from "tsyringe";
2✔
5
import { AlgorithmProvider, diAlgorithm, diAlgorithmProvider, IAlgorithm } from "./algorithm";
2✔
6
import { HashedAlgorithm } from "./types";
7

8
/**
9
 * RSA algorithm provider
10
 */
11
@injectable()
2✔
12
export class RsaAlgorithm implements IAlgorithm {
2✔
13

14
  public static createPssParams(hash: unknown, saltLength: number): asn1Rsa.RsaSaPssParams | null {
2✔
15
    const hashAlgorithm = RsaAlgorithm.getHashAlgorithm(hash);
2✔
16
    if (!hashAlgorithm) {
2!
17
      return null;
×
18
    }
×
19

20
    return new asn1Rsa.RsaSaPssParams({
2✔
21
      hashAlgorithm,
2✔
22
      maskGenAlgorithm: new AlgorithmIdentifier({
2✔
23
        algorithm: asn1Rsa.id_mgf1,
2✔
24
        parameters: AsnConvert.serialize(hashAlgorithm),
2✔
25
      }),
2✔
26
      saltLength,
2✔
27
    });
2✔
28
  }
2✔
29

30
  public static getHashAlgorithm(alg: unknown): AlgorithmIdentifier | null {
2✔
31
    const algProv = container.resolve<AlgorithmProvider>(diAlgorithmProvider);
2✔
32
    if (typeof alg === "string") {
2!
33
      return algProv.toAsnAlgorithm({ name: alg });
×
34
    } if (typeof alg === "object" && alg && "name" in alg) {
2✔
35
      return algProv.toAsnAlgorithm(alg as Algorithm);
2✔
36
    }
2!
37

38
    return null;
×
39
  }
2✔
40

41
  public toAsnAlgorithm(alg: Algorithm): AlgorithmIdentifier | null {
2✔
42
    switch (alg.name.toLowerCase()) {
54✔
43
      case "rsassa-pkcs1-v1_5":
54✔
44
        if ("hash" in alg) {
48✔
45
          let hash: string;
46✔
46
          if (typeof alg.hash === "string") {
46✔
47
            hash = alg.hash;
4✔
48
          } else if (alg.hash && typeof alg.hash === "object"
42✔
49
            && "name" in alg.hash && typeof alg.hash.name === "string") {
42✔
50
            hash = alg.hash.name.toUpperCase();
40✔
51
          } else {
40✔
52
            throw new Error("Cannot get hash algorithm name");
2✔
53
          }
2✔
54

55
          switch (hash.toLowerCase()) {
44✔
56
            case "sha-1":
46✔
57
              return new AlgorithmIdentifier({ algorithm: asn1Rsa.id_sha1WithRSAEncryption, parameters: null });
4✔
58
            case "sha-256":
46✔
59
              return new AlgorithmIdentifier({ algorithm: asn1Rsa.id_sha256WithRSAEncryption, parameters: null });
4✔
60
            case "sha-384":
46✔
61
              return new AlgorithmIdentifier({ algorithm: asn1Rsa.id_sha384WithRSAEncryption, parameters: null });
34✔
62
            case "sha-512":
46!
63
              return new AlgorithmIdentifier({ algorithm: asn1Rsa.id_sha512WithRSAEncryption, parameters: null });
×
64
          }
46✔
65
        } else {
48✔
66
          return new AlgorithmIdentifier({ algorithm: asn1Rsa.id_rsaEncryption, parameters: null });
2✔
67
        }
2✔
68
        break;
2✔
69
      case "rsa-pss":
54✔
70
        if ("hash" in alg) {
2✔
71
          if (!("saltLength" in alg && typeof alg.saltLength === "number")) {
2!
72
            throw new Error("Cannot get 'saltLength' from 'alg' argument");
×
73
          }
×
74
          const pssParams = RsaAlgorithm.createPssParams(alg.hash, alg.saltLength);
2✔
75
          if (!pssParams) {
2!
76
            throw new Error("Cannot create PSS parameters");
×
77
          }
×
78

79
          return new AlgorithmIdentifier({ algorithm: asn1Rsa.id_RSASSA_PSS, parameters: AsnConvert.serialize(pssParams) });
2✔
80
        } else {
2!
81
          return new AlgorithmIdentifier({ algorithm: asn1Rsa.id_RSASSA_PSS, parameters: null });
×
82
        }
×
83
        break;
×
84
    }
54✔
85

86
    return null;
6✔
87
  }
54✔
88

89
  public toWebAlgorithm(alg: AlgorithmIdentifier): Algorithm | HashedAlgorithm | null {
2✔
90
    switch (alg.algorithm) {
164✔
91
      case asn1Rsa.id_rsaEncryption:
164✔
92
        return { name: "RSASSA-PKCS1-v1_5" };
102✔
93
      case asn1Rsa.id_sha1WithRSAEncryption:
164!
UNCOV
94
        return { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-1" } };
×
95
      case asn1Rsa.id_sha256WithRSAEncryption:
164✔
96
        return { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-256" } };
14✔
97
      case asn1Rsa.id_sha384WithRSAEncryption:
164✔
98
        return { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-384" } };
28✔
99
      case asn1Rsa.id_sha512WithRSAEncryption:
164!
100
        return { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-512" } };
×
101
      case asn1Rsa.id_RSASSA_PSS:
164✔
102
        if (alg.parameters) {
4✔
103
          const pssParams = AsnConvert.parse(alg.parameters, asn1Rsa.RsaSaPssParams);
4✔
104
          const algProv = container.resolve<AlgorithmProvider>(diAlgorithmProvider);
4✔
105
          const hashAlg = algProv.toWebAlgorithm(pssParams.hashAlgorithm);
4✔
106

107
          return {
4✔
108
            name: "RSA-PSS",
4✔
109
            hash: hashAlg,
4✔
110
            saltLength: pssParams.saltLength,
4✔
111
          } as Algorithm;
4✔
112
        } else {
4!
113
          return { name: "RSA-PSS" };
×
114
        }
×
115
    }
164✔
116

117
    return null;
16✔
118
  }
164✔
119

120
}
2✔
121

122
// register RSA algorithm provider as a singleton object
123
container.registerSingleton(diAlgorithm, RsaAlgorithm);
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc