| 1 | module pem |
| 2 | |
| 3 | import encoding.base64 |
| 4 | import arrays |
| 5 | |
| 6 | // encode encodes the given block into a |
| 7 | // string using the EncodeConfig. It returns an error if `block_type` is undefined |
| 8 | // or if a value in `headers` contains an invalid character ':' |
| 9 | // |
| 10 | // default EncodeConfig values wrap lines at 64 bytes and use '\n' for newlines |
| 11 | pub fn (block Block) encode(config EncodeConfig) !string { |
| 12 | if block.block_type == '' { |
| 13 | return error('crypto.pem: `encode` called with undefined `block_type`') |
| 14 | } |
| 15 | if block.headers.keys().any(it.contains(':')) || block.headers.values().any(it.contains(':')) { |
| 16 | return error('crypto.pem: invalid header character `:`') |
| 17 | } |
| 18 | |
| 19 | // to avoid repeated struct access |
| 20 | newline := config.line_ending |
| 21 | length := config.line_length |
| 22 | |
| 23 | mut inner := '' |
| 24 | if block.headers.len > 0 { |
| 25 | // Proc-Type must be written first if it is present |
| 26 | if block.headers['Proc-Type'].len > 0 { |
| 27 | inner += 'Proc-Type: 4,${block.headers['Proc-Type'][0].trim_string_left('4,')}' + |
| 28 | newline |
| 29 | } |
| 30 | |
| 31 | for key, value in block.headers { |
| 32 | if key == 'Proc-Type' { |
| 33 | continue |
| 34 | } |
| 35 | |
| 36 | for _, subvalue in value { |
| 37 | inner += '${key}: ' |
| 38 | if key.len + subvalue.len < length { |
| 39 | inner += subvalue |
| 40 | } else { |
| 41 | inner += newline + wrap_lines(subvalue, newline, length) |
| 42 | } |
| 43 | inner += newline |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | inner += newline |
| 48 | } |
| 49 | |
| 50 | inner += wrap_lines(base64.encode(block.data), newline, length) |
| 51 | |
| 52 | return '${pem_begin}${block.block_type}${pem_eol}${newline}' + '${inner}' + |
| 53 | '${pem_end}${block.block_type}${pem_eol}' |
| 54 | } |
| 55 | |
| 56 | @[inline] |
| 57 | fn wrap_lines(str string, newline string, length int) string { |
| 58 | return arrays.chunk(str.bytes(), length).map(it.bytestr()).join(newline) |
| 59 | } |
| 60 | |