/* * Transform an armored document in binary format * Used on public keys and signatures */ static int pgp_unarmor(const char *p_ibuf, size_t i_ibuf_len, uint8_t *p_obuf, size_t i_obuf_len) { const char *p_ipos = p_ibuf; uint8_t *p_opos = p_obuf; int i_end = 0; int i_header_skipped = 0; while (!i_end && p_ipos < p_ibuf + i_ibuf_len && *p_ipos != '=') { if (*p_ipos == '\r' || *p_ipos == '\n') { p_ipos++; continue; } size_t i_line_len = strcspn(p_ipos, "\r\n"); if (i_line_len == 0) continue; if (!i_header_skipped) { if (!strncmp(p_ipos, "-----BEGIN PGP", 14)) i_header_skipped = 1; p_ipos += i_line_len + 1; continue; } if (!strncmp(p_ipos, "Version:", 8)) { p_ipos += i_line_len + 1; continue; } if (p_ipos[i_line_len - 1] == '=') { i_end = 1; } p_opos += b64_decode_binary_to_buffer(p_opos, p_obuf - p_opos + i_obuf_len, p_ipos, (int)i_line_len); p_ipos += i_line_len + 1; } if (p_ipos + 1 < p_ibuf + i_ibuf_len && (*p_ipos == '\r' || *p_ipos == '\n')) p_ipos++; /* XXX: the CRC is OPTIONAL, really require it ? */ if (p_ipos + 5 > p_ibuf + i_ibuf_len || *p_ipos++ != '=') return 0; uint8_t p_crc[3]; if (b64_decode_binary_to_buffer(p_crc, sizeof(p_crc), p_ipos, 5) != 3) return 0; long l_crc = crc_octets(p_obuf, p_opos - p_obuf); long l_crc2 = (0 << 24) + (p_crc[0] << 16) + (p_crc[1] << 8) + p_crc[2]; return (int)((l_crc2 == l_crc) ? p_opos - p_obuf : 0); }
value caml_crc_octets(value data) { CAMLparam1(data); CAMLlocal1(rval); char *octets = String_val(data); size_t len = string_length(data); long crc = crc_octets(octets,len); rval = Val_int(crc); CAMLreturn(rval); }