-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
145 lines (126 loc) · 4.08 KB
/
index.js
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
'use strict'
const PATTERN_KEY_BEGIN = /^----[- ]BEGIN (?<label>(?:(?:[A-Z][A-Z0-9]+) )?(?<type>PRIVATE|PUBLIC) KEY)[ -]----/
const PATTERN_KEY_END = /----[- ]END (?<label>(?:(?:[A-Z][A-Z0-9]+) )?(?<type>PRIVATE|PUBLIC) KEY)[ -]----$/
const PATTERN_X509_BEGIN = /^-----BEGIN (?<label>(?:(?:TRUSTED |X509 )?(?<t1>CERTIFICATE))|(?:(?:NEW )?CERTIFICATE (?<t2>REQUEST))|(?:X509 (?<t3>CRL)))-----/
const PATTERN_X509_END = /-----END (?<label>(?:(?:TRUSTED |X509 )?(?<t1>CERTIFICATE))|(?:(?:NEW )?CERTIFICATE (?<t2>REQUEST))|(?:X509 (?<t3>CRL)))-----$/
;(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory)
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory()
} else {
// Browser globals (root is window)
root.PemMatch = factory()
}
}(typeof self !== 'undefined' ? self : this, function () {
// Just return a value to define the module export.
// This example returns an object, but the module
// can return a function as the exported value.
return {
matchKey,
matchKeyBegin: pem => matchBegin(pem, PATTERN_KEY_BEGIN),
matchKeyEnd: pem => matchEnd(pem, PATTERN_KEY_END),
matchX509,
matchX509Begin: pem => matchBegin(pem, PATTERN_X509_BEGIN),
matchX509End: pem => matchEnd(pem, PATTERN_X509_END),
isPrivateKey,
isPublicKey,
isX509Cert: pem => isX509(pem, 'CERTFICATE'),
isX509Request: pem => isX509(pem, 'REQUEST'),
isX509CRL: pem => isX509(pem, 'CRL'),
trimLines
}
}))
function isPrivateKey (pem) {
const match = matchKey(pem)
if (match && match.type === 'PRIVATE') {
return match.label
}
}
function isPublicKey (pem) {
const match = matchKey(pem)
if (match && match.type === 'PUBLIC') {
return match.label
}
}
function isX509 (pem, suffix) {
const match = matchX509(pem)
if (match && match.label.endsWith(suffix)) {
return match.label
}
}
function matchKey (pem) {
const beginMatch = matchBegin(pem, PATTERN_KEY_BEGIN)
const endMatch = matchEnd(pem, PATTERN_KEY_END)
if (beginMatch && endMatch) {
if (beginMatch.label !== endMatch.label ||
beginMatch.type !== endMatch.type) {
return
}
const key = trimLines(pem).replace(PATTERN_KEY_BEGIN, '')
.replace(PATTERN_KEY_END, '')
if (isValidBase64(key)) {
return beginMatch
}
}
}
function isValidBase64 (content) {
if (content && typeof content === 'string') {
const joinedLines = content.replace(/[\r\n]/g, '')
if (!joinedLines) {
return false
}
if (typeof atob === 'function') {
try {
// eslint-disable-next-line no-undef
return !!atob(joinedLines)
} catch (err) {
}
} else {
const decodeLen = Buffer.from(joinedLines, 'base64').length
const originLen = joinedLines.length / 4 * 3
return decodeLen > 0 && decodeLen >= originLen - 2
}
}
}
function matchX509 (pem) {
const beginMatch = matchBegin(pem, PATTERN_X509_BEGIN)
const endMatch = matchEnd(pem, PATTERN_X509_END)
if (beginMatch && endMatch) {
beginMatch.type = beginMatch.t1 || beginMatch.t2 || beginMatch.t3
endMatch.type = endMatch.t1 || endMatch.t2 || endMatch.t3
if (beginMatch.label !== endMatch.label ||
beginMatch.type !== endMatch.type) {
return
}
const key = trimLines(pem).replace(PATTERN_X509_BEGIN, '')
.replace(PATTERN_X509_END, '')
if (isValidBase64(key)) {
return beginMatch
}
}
}
function matchBegin (pem, pattern) {
const lines = trimLines(pem)
if (lines) {
const match = trimLines(lines).match(pattern)
return match && match.groups
}
}
function matchEnd (pem, pattern) {
const lines = trimLines(pem)
if (lines) {
const lastLine = lines.substring(lines.lastIndexOf('\n') + 1)
const match = lastLine.match(pattern)
return match && match.groups
}
}
function trimLines (input) {
if (typeof input === 'string') {
return input.trim()
}
}