-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathssri.ts
More file actions
131 lines (125 loc) · 4.04 KB
/
ssri.ts
File metadata and controls
131 lines (125 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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
/**
* @fileoverview SSRI (Subresource Integrity) hash format utilities.
* Provides conversion and validation for SSRI and hex hash formats.
*/
import { BufferFrom, BufferPrototypeToString, ErrorCtor } from './primordials'
/**
* Convert hex format hash to SSRI format.
*
* Takes a hash in hex format and converts it to SSRI format with the specified
* algorithm prefix (defaults to sha256).
*
* @param hex - Hash in hex format
* @param algorithm - Hash algorithm (default: 'sha256')
* @returns SSRI format hash (algorithm-base64)
* @throws Error if hex format is invalid
*
* @example
* ```typescript
* const ssri = hexToSsri('76682a9fc3bbe62975176e2541f39a8168877d828d5cad8b56461fc36ac2b856')
* // Returns: 'sha256-dmgqn8O75il1F24lQfOagWiHfYKNXK2LVkYfw2rCuFY='
* ```
*/
/*@__NO_SIDE_EFFECTS__*/
export function hexToSsri(hex: string, algorithm = 'sha256'): string {
if (!/^[a-f0-9]+$/i.test(hex)) {
throw new ErrorCtor(`Invalid hex format: ${hex}`)
}
// Convert hex to base64.
const buffer = BufferFrom!(hex, 'hex')
const base64Hash = BufferPrototypeToString!(buffer, 'base64')
return `${algorithm}-${base64Hash}`
}
/**
* Check if a string is valid hex format.
*
* Validates that a string contains only hexadecimal characters (0-9, a-f).
* Does not verify hash length or algorithm.
*
* @param value - String to validate
* @returns True if string is valid hex format
*
* @example
* ```typescript
* isValidHex('76682a9fc3bbe62975176e2541f39a8168877d828d5cad8b56461fc36ac2b856') // true
* isValidHex('sha256-dmgqn8O75il1F24lQfOagWiHfYKNXK2LVkYfw2rCuFY=') // false
* ```
*/
/*@__NO_SIDE_EFFECTS__*/
export function isValidHex(value: string): boolean {
return /^[a-f0-9]+$/i.test(value)
}
/**
* Check if a string is valid SSRI format.
*
* Validates that a string matches the SSRI format pattern (algorithm-base64).
* Does not verify that the base64 encoding is valid.
*
* @param value - String to validate
* @returns True if string matches SSRI format
*
* @example
* ```typescript
* isValidSsri('sha256-dmgqn8O75il1F24lQfOagWiHfYKNXK2LVkYfw2rCuFY=') // true
* isValidSsri('76682a9f...') // false
* ```
*/
/*@__NO_SIDE_EFFECTS__*/
export function isValidSsri(value: string): boolean {
return /^[a-z0-9]+-[A-Za-z0-9+/]{2,}=*$/i.test(value)
}
/**
* Parse SSRI format into components.
*
* Extracts the algorithm and base64 hash from an SSRI string.
*
* @param ssri - Hash in SSRI format
* @returns Object with algorithm and base64Hash properties
* @throws Error if SSRI format is invalid
*
* @example
* ```typescript
* const { algorithm, base64Hash } = parseSsri('sha256-dmgqn8O75il1F24lQfOagWiHfYKNXK2LVkYfw2rCuFY=')
* // Returns: { algorithm: 'sha256', base64Hash: 'dmgqn8O75il1F24lQfOagWiHfYKNXK2LVkYfw2rCuFY=' }
* ```
*/
/*@__NO_SIDE_EFFECTS__*/
export function parseSsri(ssri: string): {
algorithm: string
base64Hash: string
} {
const match = /^([a-z0-9]+)-([A-Za-z0-9+/]+=*)$/i.exec(ssri)
if (!match || !match[1] || !match[2] || match[2].length < 2) {
throw new ErrorCtor(`Invalid SSRI format: ${ssri}`)
}
const algorithm = match[1]
const base64Hash = match[2]
return { algorithm, base64Hash }
}
/**
* Convert SSRI format hash to hex format.
*
* Takes a hash in SSRI format (e.g., "sha256-base64hash") and converts it to
* standard hex format (e.g., "hexstring").
*
* @param ssri - Hash in SSRI format (algorithm-base64)
* @returns Hex string representation of the hash
* @throws Error if SSRI format is invalid
*
* @example
* ```typescript
* const hex = ssriToHex('sha256-dmgqn8O75il1F24lQfOagWiHfYKNXK2LVkYfw2rCuFY=')
* // Returns: '76682a9fc3bbe62975176e2541f39a8168877d828d5cad8b56461fc36ac2b856'
* ```
*/
/*@__NO_SIDE_EFFECTS__*/
export function ssriToHex(ssri: string): string {
const match = /^([a-z0-9]+)-([A-Za-z0-9+/]+=*)$/i.exec(ssri)
if (!match || !match[2] || match[2].length < 2) {
throw new ErrorCtor(`Invalid SSRI format: ${ssri}`)
}
const base64Hash = match[2]
// Convert base64 to hex.
const buffer = BufferFrom!(base64Hash, 'base64')
return BufferPrototypeToString!(buffer, 'hex')
}