decode.c (2670B)
1 #include <stdlib.h> 2 #include <string.h> 3 4 #include "common.h" 5 #include "scan.h" 6 #include "orlp/ed25519.h" 7 8 #ifdef __cplusplus 9 extern "C" { 10 #endif 11 12 static int hdr_hexval(unsigned char c) { 13 if (c >= '0' && c <= '9') return c - '0'; 14 if (c >= 'a' && c <= 'f') return c - 'a' + 10; 15 if (c >= 'A' && c <= 'F') return c - 'A' + 10; 16 return -1; 17 } 18 19 // Parse exactly hexlen hex chars into out; returns 1 on success. 20 static int hdr_parse_hex(const unsigned char *val, size_t vallen, 21 unsigned char *out, size_t hexlen) { 22 size_t i; 23 int hi, lo; 24 if (vallen != hexlen * 2) return 0; 25 for (i = 0; i < hexlen; i++) { 26 hi = hdr_hexval(val[i * 2]); 27 lo = hdr_hexval(val[i * 2 + 1]); 28 if (hi < 0 || lo < 0) return 0; 29 out[i] = (unsigned char)((hi << 4) | lo); 30 } 31 return 1; 32 } 33 34 struct KeyPair * fmt_hdr_decode(unsigned char *cipherdata, size_t len) { 35 const unsigned char *pos = cipherdata; 36 const unsigned char *end = cipherdata + len; 37 const unsigned char *line; 38 size_t linelen; 39 int which; 40 const unsigned char *val; 41 size_t vallen; 42 unsigned char pub[32]; 43 unsigned char priv[64]; 44 int seen_pub = 0, have_pub = 0; 45 int seen_priv = 0, have_priv = 0; 46 struct KeyPair *kp; 47 48 // First valid occurrence of each label wins; malformed hex runs are 49 // ignored so a later valid block in the stream can still win. 50 while (hdr_next_line(&pos, end, &line, &linelen)) { 51 if (!hdr_match_label(line, linelen, &which, &val, &vallen)) continue; 52 if (which == 1 && seen_pub) continue; 53 if (which == 2 && seen_priv) continue; 54 if (vallen == 0) continue; 55 // Parenthesized value marks the field absent (e.g. "(no private key)") 56 if (val[0] == '(') { 57 if (which == 1) seen_pub = 1; 58 else seen_priv = 1; 59 continue; 60 } 61 if (which == 1) { 62 if (!hdr_parse_hex(val, vallen, pub, 32)) continue; 63 seen_pub = 1; 64 have_pub = 1; 65 } else { 66 if (!hdr_parse_hex(val, vallen, priv, 64)) continue; 67 seen_priv = 1; 68 have_priv = 1; 69 } 70 } 71 72 if (!have_pub && !have_priv) return NULL; 73 74 // A lone private key still yields its public half via scalar mult 75 if (!have_pub) { 76 ed25519_derive_pubkey(pub, priv); 77 have_pub = 1; 78 } 79 80 kp = calloc(1, sizeof(struct KeyPair)); 81 if (!kp) return NULL; 82 kp->public_key = calloc(1, 32); 83 if (!kp->public_key) { 84 free(kp); 85 return NULL; 86 } 87 memcpy(kp->public_key, pub, 32); 88 if (have_priv) { 89 kp->private_key = calloc(1, 64); 90 if (!kp->private_key) { 91 free(kp->public_key); 92 free(kp); 93 return NULL; 94 } 95 memcpy(kp->private_key, priv, 64); 96 } 97 return kp; 98 } 99 100 #ifdef __cplusplus 101 } // extern "C" 102 #endif