RSAESOAEPParams.ts (8025B)
1 import * as asn1js from "asn1js"; 2 import * as pvutils from "pvutils"; 3 import { AlgorithmIdentifier, AlgorithmIdentifierJson, AlgorithmIdentifierSchema } from "./AlgorithmIdentifier"; 4 import { EMPTY_STRING } from "./constants"; 5 import { AsnError } from "./errors"; 6 import { PkiObject, PkiObjectParameters } from "./PkiObject"; 7 import * as Schema from "./Schema"; 8 9 const HASH_ALGORITHM = "hashAlgorithm"; 10 const MASK_GEN_ALGORITHM = "maskGenAlgorithm"; 11 const P_SOURCE_ALGORITHM = "pSourceAlgorithm"; 12 const CLEAR_PROPS = [ 13 HASH_ALGORITHM, 14 MASK_GEN_ALGORITHM, 15 P_SOURCE_ALGORITHM 16 ]; 17 18 export interface IRSAESOAEPParams { 19 hashAlgorithm: AlgorithmIdentifier; 20 maskGenAlgorithm: AlgorithmIdentifier; 21 pSourceAlgorithm: AlgorithmIdentifier; 22 } 23 24 export interface RSAESOAEPParamsJson { 25 hashAlgorithm?: AlgorithmIdentifierJson; 26 maskGenAlgorithm?: AlgorithmIdentifierJson; 27 pSourceAlgorithm?: AlgorithmIdentifierJson; 28 } 29 30 export type RSAESOAEPParamsParameters = PkiObjectParameters & Partial<IRSAESOAEPParams>; 31 32 /** 33 * Class from RFC3447 34 */ 35 export class RSAESOAEPParams extends PkiObject implements IRSAESOAEPParams { 36 37 public static override CLASS_NAME = "RSAESOAEPParams"; 38 39 public hashAlgorithm!: AlgorithmIdentifier; 40 public maskGenAlgorithm!: AlgorithmIdentifier; 41 public pSourceAlgorithm!: AlgorithmIdentifier; 42 43 /** 44 * Initializes a new instance of the {@link RSAESOAEPParams} class 45 * @param parameters Initialization parameters 46 */ 47 constructor(parameters: RSAESOAEPParamsParameters = {}) { 48 super(); 49 50 this.hashAlgorithm = pvutils.getParametersValue(parameters, HASH_ALGORITHM, RSAESOAEPParams.defaultValues(HASH_ALGORITHM)); 51 this.maskGenAlgorithm = pvutils.getParametersValue(parameters, MASK_GEN_ALGORITHM, RSAESOAEPParams.defaultValues(MASK_GEN_ALGORITHM)); 52 this.pSourceAlgorithm = pvutils.getParametersValue(parameters, P_SOURCE_ALGORITHM, RSAESOAEPParams.defaultValues(P_SOURCE_ALGORITHM)); 53 54 if (parameters.schema) { 55 this.fromSchema(parameters.schema); 56 } 57 } 58 59 /** 60 * Returns default values for all class members 61 * @param memberName String name for a class member 62 * @returns Default value 63 */ 64 public static override defaultValues(memberName: typeof HASH_ALGORITHM): AlgorithmIdentifier; 65 public static override defaultValues(memberName: typeof MASK_GEN_ALGORITHM): AlgorithmIdentifier; 66 public static override defaultValues(memberName: typeof P_SOURCE_ALGORITHM): AlgorithmIdentifier; 67 public static override defaultValues(memberName: string): any { 68 switch (memberName) { 69 case HASH_ALGORITHM: 70 return new AlgorithmIdentifier({ 71 algorithmId: "1.3.14.3.2.26", // SHA-1 72 algorithmParams: new asn1js.Null() 73 }); 74 case MASK_GEN_ALGORITHM: 75 return new AlgorithmIdentifier({ 76 algorithmId: "1.2.840.113549.1.1.8", // MGF1 77 algorithmParams: (new AlgorithmIdentifier({ 78 algorithmId: "1.3.14.3.2.26", // SHA-1 79 algorithmParams: new asn1js.Null() 80 })).toSchema() 81 }); 82 case P_SOURCE_ALGORITHM: 83 return new AlgorithmIdentifier({ 84 algorithmId: "1.2.840.113549.1.1.9", // id-pSpecified 85 algorithmParams: new asn1js.OctetString({ valueHex: (new Uint8Array([0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09])).buffer }) // SHA-1 hash of empty string 86 }); 87 default: 88 return super.defaultValues(memberName); 89 } 90 } 91 92 /** 93 * @inheritdoc 94 * @asn ASN.1 schema 95 * ```asn 96 * RSAES-OAEP-params ::= SEQUENCE { 97 * hashAlgorithm [0] HashAlgorithm DEFAULT sha1, 98 * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, 99 * pSourceAlgorithm [2] PSourceAlgorithm DEFAULT pSpecifiedEmpty 100 * } 101 *``` 102 */ 103 public static override schema(parameters: Schema.SchemaParameters<{ 104 hashAlgorithm?: AlgorithmIdentifierSchema; 105 maskGenAlgorithm?: AlgorithmIdentifierSchema; 106 pSourceAlgorithm?: AlgorithmIdentifierSchema; 107 }> = {}): Schema.SchemaType { 108 const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {}); 109 110 return (new asn1js.Sequence({ 111 name: (names.blockName || EMPTY_STRING), 112 value: [ 113 new asn1js.Constructed({ 114 idBlock: { 115 tagClass: 3, // CONTEXT-SPECIFIC 116 tagNumber: 0 // [0] 117 }, 118 optional: true, 119 value: [AlgorithmIdentifier.schema(names.hashAlgorithm || {})] 120 }), 121 new asn1js.Constructed({ 122 idBlock: { 123 tagClass: 3, // CONTEXT-SPECIFIC 124 tagNumber: 1 // [1] 125 }, 126 optional: true, 127 value: [AlgorithmIdentifier.schema(names.maskGenAlgorithm || {})] 128 }), 129 new asn1js.Constructed({ 130 idBlock: { 131 tagClass: 3, // CONTEXT-SPECIFIC 132 tagNumber: 2 // [2] 133 }, 134 optional: true, 135 value: [AlgorithmIdentifier.schema(names.pSourceAlgorithm || {})] 136 }) 137 ] 138 })); 139 } 140 141 public fromSchema(schema: Schema.SchemaType): void { 142 // Clear input data first 143 pvutils.clearProps(schema, CLEAR_PROPS); 144 145 // Check the schema is valid 146 const asn1 = asn1js.compareSchema(schema, 147 schema, 148 RSAESOAEPParams.schema({ 149 names: { 150 hashAlgorithm: { 151 names: { 152 blockName: HASH_ALGORITHM 153 } 154 }, 155 maskGenAlgorithm: { 156 names: { 157 blockName: MASK_GEN_ALGORITHM 158 } 159 }, 160 pSourceAlgorithm: { 161 names: { 162 blockName: P_SOURCE_ALGORITHM 163 } 164 } 165 } 166 }) 167 ); 168 AsnError.assertSchema(asn1, this.className); 169 170 // Get internal properties from parsed schema 171 if (HASH_ALGORITHM in asn1.result) 172 this.hashAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.hashAlgorithm }); 173 174 if (MASK_GEN_ALGORITHM in asn1.result) 175 this.maskGenAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.maskGenAlgorithm }); 176 177 if (P_SOURCE_ALGORITHM in asn1.result) 178 this.pSourceAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.pSourceAlgorithm }); 179 } 180 181 public toSchema(): asn1js.Sequence { 182 //#region Create array for output sequence 183 const outputArray = []; 184 185 if (!this.hashAlgorithm.isEqual(RSAESOAEPParams.defaultValues(HASH_ALGORITHM))) { 186 outputArray.push(new asn1js.Constructed({ 187 idBlock: { 188 tagClass: 3, // CONTEXT-SPECIFIC 189 tagNumber: 0 // [0] 190 }, 191 value: [this.hashAlgorithm.toSchema()] 192 })); 193 } 194 195 if (!this.maskGenAlgorithm.isEqual(RSAESOAEPParams.defaultValues(MASK_GEN_ALGORITHM))) { 196 outputArray.push(new asn1js.Constructed({ 197 idBlock: { 198 tagClass: 3, // CONTEXT-SPECIFIC 199 tagNumber: 1 // [1] 200 }, 201 value: [this.maskGenAlgorithm.toSchema()] 202 })); 203 } 204 205 if (!this.pSourceAlgorithm.isEqual(RSAESOAEPParams.defaultValues(P_SOURCE_ALGORITHM))) { 206 outputArray.push(new asn1js.Constructed({ 207 idBlock: { 208 tagClass: 3, // CONTEXT-SPECIFIC 209 tagNumber: 2 // [2] 210 }, 211 value: [this.pSourceAlgorithm.toSchema()] 212 })); 213 } 214 //#endregion 215 216 //#region Construct and return new ASN.1 schema for this object 217 return (new asn1js.Sequence({ 218 value: outputArray 219 })); 220 //#endregion 221 } 222 223 public toJSON(): RSAESOAEPParamsJson { 224 const res: RSAESOAEPParamsJson = {}; 225 226 if (!this.hashAlgorithm.isEqual(RSAESOAEPParams.defaultValues(HASH_ALGORITHM))) { 227 res.hashAlgorithm = this.hashAlgorithm.toJSON(); 228 } 229 230 if (!this.maskGenAlgorithm.isEqual(RSAESOAEPParams.defaultValues(MASK_GEN_ALGORITHM))) { 231 res.maskGenAlgorithm = this.maskGenAlgorithm.toJSON(); 232 } 233 234 if (!this.pSourceAlgorithm.isEqual(RSAESOAEPParams.defaultValues(P_SOURCE_ALGORITHM))) { 235 res.pSourceAlgorithm = this.pSourceAlgorithm.toJSON(); 236 } 237 238 return res; 239 } 240 241 }