1 | var assert = require('assert')
|
2 | , writeHeader = require('../utils/writeHeader')
|
3 |
|
4 | function writeHeader (header) {
|
5 | var keys = Object.keys(header || {})
|
6 | return keys.map(function (k) {
|
7 | var line = k + ': ' + header[k] + '\n'
|
8 | return line.length > 64
|
9 | ? line.slice(0, 64) + '\n ' + line.slice(64).match(/.{1,63}/g).join('\n ') + '\n'
|
10 | : line
|
11 | }).join('') + (keys.length ? '\n' : '')
|
12 | }
|
13 |
|
14 | function parseMessage (str) {
|
15 | assert(typeof str === 'string')
|
16 | var lines = str.split('\n'), line, chunks = []
|
17 | var tag = 'SALTY SIGNED MESSAGE'
|
18 | var tagFound = false, endFound = false, headerParsed = false, headerKey, headerValue
|
19 | var header = {}
|
20 | var beginRE = new RegExp('-----\\s*BEGIN ' + tag + '\\s*-----')
|
21 | var endRE = new RegExp('-----\\s*END ' + tag + '\\s*-----')
|
22 | while (lines.length) {
|
23 | var line = lines.shift()
|
24 | if (!tagFound) {
|
25 | var tagMatch = line.match(beginRE)
|
26 | if (tagMatch) tagFound = true
|
27 | }
|
28 | else if (!headerParsed) {
|
29 | if (!line) {
|
30 | headerParsed = true
|
31 | continue
|
32 | }
|
33 | else {
|
34 | var headerMatch = line.match(/^([^:]+): (.*)/)
|
35 | if (!headerMatch) {
|
36 | var headerContMatch = line.match(/^ (.{1,63})/)
|
37 | if (headerContMatch) {
|
38 | assert(headerValue)
|
39 | headerValue += headerContMatch[1].trim()
|
40 | }
|
41 | else {
|
42 | chunks.push(line)
|
43 | headerParsed = true
|
44 | }
|
45 | continue
|
46 | }
|
47 | if (headerValue) {
|
48 | header[headerKey] = headerValue
|
49 | }
|
50 | headerKey = headerMatch[1].toLowerCase()
|
51 | headerValue = headerMatch[2].trim()
|
52 | }
|
53 | }
|
54 | else {
|
55 | var endMatch = line.match(endRE)
|
56 | if (endMatch) {
|
57 | endFound = true
|
58 | break
|
59 | }
|
60 | chunks.push(line)
|
61 | }
|
62 | }
|
63 |
|
64 | if (headerValue) {
|
65 | header[headerKey] = headerValue
|
66 | }
|
67 |
|
68 | assert(tagFound)
|
69 | assert(endFound)
|
70 |
|
71 | var str, body
|
72 |
|
73 | if (header['content-transfer-encoding'] === 'base64') {
|
74 | str = chunks.map(function (line) {
|
75 | return line.trim()
|
76 | }).join('')
|
77 | body = Buffer(str, 'base64')
|
78 | }
|
79 | else {
|
80 | str = chunks.join('\n')
|
81 | body = Buffer(str)
|
82 | }
|
83 |
|
84 | return {
|
85 | header: header,
|
86 | body: body
|
87 | }
|
88 | }
|
89 |
|
90 | function createMessage (header, buf) {
|
91 | var finalHeader = writeHeader(header)
|
92 | var out = '-----BEGIN SALTY SIGNED MESSAGE-----\n'
|
93 | out += finalHeader + '\n'
|
94 | if (header['content-transfer-encoding'] === '8bit') {
|
95 | out += buf.toString('utf8')
|
96 | }
|
97 | else {
|
98 | out += buf.toString('base64').match(/.{1,64}/g).join('\n')
|
99 | }
|
100 | out += '\n-----END SALTY SIGNED MESSAGE-----'
|
101 | return out
|
102 | }
|
103 |
|
104 | module.exports = {
|
105 | parse: parseMessage,
|
106 | create: createMessage
|
107 | } |
\ | No newline at end of file |