23 #include "mrmailbox_internal.h" 35 void mr_wipe_secret_mem(
void* buf,
size_t buf_bytes)
38 if( buf == NULL || buf_bytes <= 0 ) {
42 memset(buf, 0x00, buf_bytes);
46 static void mrkey_empty(mrkey_t* ths)
52 if( ths->m_type==MR_PRIVATE ) {
53 mr_wipe_secret_mem(ths->m_binary, ths->m_bytes);
59 ths->m_type = MR_PUBLIC;
67 if( (ths=calloc(1,
sizeof(mrkey_t)))==NULL ) {
70 ths->_m_heap_refcnt = 1;
75 mrkey_t* mrkey_ref(mrkey_t* ths)
80 ths->_m_heap_refcnt++;
85 void mrkey_unref(mrkey_t* ths)
91 ths->_m_heap_refcnt--;
92 if( ths->_m_heap_refcnt != 0 ) {
101 int mrkey_set_from_raw(mrkey_t* ths,
const void* data,
int bytes,
int type)
104 if( ths==NULL || data==NULL || bytes <= 0 ) {
107 ths->m_binary = malloc(bytes);
108 if( ths->m_binary == NULL ) {
111 memcpy(ths->m_binary, data, bytes);
112 ths->m_bytes = bytes;
118 int mrkey_set_from_key(mrkey_t* ths,
const mrkey_t* o)
121 if( ths==NULL || o==NULL ) {
124 return mrkey_set_from_raw(ths, o->m_binary, o->m_bytes, o->m_type);
128 int mrkey_set_from_stmt(mrkey_t* ths, sqlite3_stmt* stmt,
int index,
int type)
131 if( ths==NULL || stmt==NULL ) {
134 return mrkey_set_from_raw(ths, (
unsigned char*)sqlite3_column_blob(stmt, index), sqlite3_column_bytes(stmt, index), type);
138 int mrkey_set_from_base64(mrkey_t* ths,
const char* base64,
int type)
140 size_t indx = 0, result_len = 0;
145 if( ths==NULL || base64==NULL ) {
149 if( mailmime_base64_body_parse(base64, strlen(base64), &indx, &result, &result_len)!=MAILIMF_NO_ERROR
150 || result == NULL || result_len == 0 ) {
154 mrkey_set_from_raw(ths, result, result_len, type);
155 mmap_string_unref(result);
161 int mrkey_set_from_file(mrkey_t* ths,
const char* pathNfilename,
mrmailbox_t* mailbox)
166 int type = -1, success = 0;
170 if( ths==NULL || pathNfilename==NULL ) {
174 if( !mr_read_file(pathNfilename, (
void**)&buf, &buf_bytes, mailbox)
175 || buf_bytes < 50 ) {
179 mr_remove_cr_chars(buf);
182 if( strncmp(buf,
"-----BEGIN PGP PUBLIC KEY BLOCK-----\n", 37)==0 ) {
183 if( mr_str_replace(&buf,
"-----END PGP PUBLIC KEY BLOCK-----",
"")!=1 ) {
184 mrmailbox_log_warning(mailbox, 0,
"Bad header for key \"%s\".", pathNfilename);
190 else if( strncmp(buf,
"-----BEGIN PGP PRIVATE KEY BLOCK-----\n", 38)==0 ) {
191 if( mr_str_replace(&buf,
"-----END PGP PRIVATE KEY BLOCK-----",
"")!=1 ) {
192 mrmailbox_log_warning(mailbox, 0,
"Bad header for key \"%s\".", pathNfilename);
199 mrmailbox_log_warning(mailbox, 0,
"Header missing for key \"%s\".", pathNfilename);
204 p2 = strstr(p1,
"\n\n");
209 if( !mrkey_set_from_base64(ths, p1, type) ) {
210 mrmailbox_log_warning(mailbox, 0,
"Bad data in key \"%s\".", pathNfilename);
222 int mrkey_equals(
const mrkey_t* ths,
const mrkey_t* o)
224 if( ths==NULL || o==NULL
225 || ths->m_binary==NULL || ths->m_bytes<=0 || o->m_binary==NULL || o->m_bytes<=0 ) {
229 if( ths->m_bytes != o->m_bytes ) {
233 if( ths->m_type != o->m_type ) {
237 return memcmp(ths->m_binary, o->m_binary, o->m_bytes)==0? 1 : 0;
246 int mrkey_save_self_keypair__(
const mrkey_t* public_key,
const mrkey_t* private_key,
const char* addr,
int is_default, mrsqlite3_t* sql)
250 if( public_key==NULL || private_key==NULL || addr==NULL || sql==NULL
251 || public_key->m_binary==NULL || private_key->m_binary==NULL ) {
255 stmt = mrsqlite3_predefine__(sql, INSERT_INTO_keypairs_aippc,
256 "INSERT INTO keypairs (addr, is_default, public_key, private_key, created) VALUES (?,?,?,?,?);");
257 sqlite3_bind_text (stmt, 1, addr, -1, SQLITE_STATIC);
258 sqlite3_bind_int (stmt, 2, is_default);
259 sqlite3_bind_blob (stmt, 3, public_key->m_binary, public_key->m_bytes, SQLITE_STATIC);
260 sqlite3_bind_blob (stmt, 4, private_key->m_binary, private_key->m_bytes, SQLITE_STATIC);
261 sqlite3_bind_int64(stmt, 5, time(NULL));
262 if( sqlite3_step(stmt) != SQLITE_DONE ) {
270 int mrkey_load_self_public__(mrkey_t* ths,
const char* self_addr, mrsqlite3_t* sql)
274 if( ths==NULL || self_addr==NULL || sql==NULL ) {
279 stmt = mrsqlite3_predefine__(sql, SELECT_public_key_FROM_keypairs_WHERE_default,
280 "SELECT public_key FROM keypairs WHERE addr=? AND is_default=1;");
281 sqlite3_bind_text (stmt, 1, self_addr, -1, SQLITE_STATIC);
282 if( sqlite3_step(stmt) != SQLITE_ROW ) {
285 mrkey_set_from_stmt(ths, stmt, 0, MR_PUBLIC);
290 int mrkey_load_self_private__(mrkey_t* ths,
const char* self_addr, mrsqlite3_t* sql)
294 if( ths==NULL || self_addr==NULL || sql==NULL ) {
299 stmt = mrsqlite3_predefine__(sql, SELECT_private_key_FROM_keypairs_WHERE_default,
300 "SELECT private_key FROM keypairs WHERE addr=? AND is_default=1;");
301 sqlite3_bind_text (stmt, 1, self_addr, -1, SQLITE_STATIC);
302 if( sqlite3_step(stmt) != SQLITE_ROW ) {
305 mrkey_set_from_stmt(ths, stmt, 0, MR_PRIVATE);
315 static long crc_octets(
const unsigned char *octets,
size_t len)
317 #define CRC24_INIT 0xB704CEL 318 #define CRC24_POLY 0x1864CFBL 319 long crc = CRC24_INIT;
322 crc ^= (*octets++) << 16;
323 for (i = 0; i < 8; i++) {
329 return crc & 0xFFFFFFL;
333 char* mr_render_base64(
const void* buf,
size_t buf_bytes,
int break_every,
const char* break_chars,
338 if( buf==NULL || buf_bytes<=0 ) {
342 if( (ret = encode_base64((
const char*)buf, buf_bytes))==NULL ) {
347 if( add_checksum == 1 ) {
348 long checksum = crc_octets(buf, buf_bytes);
350 c[0] = (uint8_t)((checksum >> 16)&0xFF);
351 c[1] = (uint8_t)((checksum >> 8)&0xFF);
352 c[2] = (uint8_t)((checksum)&0xFF);
353 char* c64 = encode_base64((
const char*)c, 3);
355 ret = mr_mprintf(
"%s=%s", temp, c64);
361 if( break_every>0 ) {
363 ret = mr_insert_breaks(temp, break_every, break_chars);
367 if( add_checksum == 2 ) {
368 long checksum = crc_octets(buf, buf_bytes);
370 c[0] = (uint8_t)((checksum >> 16)&0xFF);
371 c[1] = (uint8_t)((checksum >> 8)&0xFF);
372 c[2] = (uint8_t)((checksum)&0xFF);
373 char* c64 = encode_base64((
const char*)c, 3);
375 ret = mr_mprintf(
"%s%s=%s", temp, break_chars, c64);
385 char* mrkey_render_base64(
const mrkey_t* ths,
int break_every,
const char* break_chars,
int add_checksum)
390 return mr_render_base64(ths->m_binary, ths->m_bytes, break_every, break_chars, add_checksum);
394 char* mrkey_render_asc(
const mrkey_t* ths,
const char* add_header_lines )
397 char *base64 = NULL, *ret = NULL;
403 if( (base64=mrkey_render_base64(ths, 76,
"\r\n", 2))==NULL ) {
407 ret = mr_mprintf(
"-----BEGIN PGP %s KEY BLOCK-----\r\n%s\r\n%s\r\n-----END PGP %s KEY BLOCK-----\r\n",
408 ths->m_type==MR_PUBLIC?
"PUBLIC" :
"PRIVATE",
409 add_header_lines? add_header_lines :
"",
411 ths->m_type==MR_PUBLIC?
"PUBLIC" :
"PRIVATE");
419 char* mr_render_fingerprint(
const uint8_t* data,
size_t bytes)
424 if( data ==NULL || bytes <= 0 ) {
425 return safe_strdup(
"ErrFingerprint2");
428 char* ret = malloc(bytes*4+1);
if( ret==NULL ) { exit(46); }
431 for( i = 0; i < bytes; i++ ) {
432 temp = mr_mprintf(
"%02X%s", (
int)data[i], (i==6||i==13)?
"\n":
" ");
441 char* mrkey_render_fingerprint(
const mrkey_t* key,
mrmailbox_t* mailbox)
443 uint8_t* fingerprint_buf = NULL;
444 size_t fingerprint_bytes = 0;
446 if( key==NULL || mailbox == NULL ) {
447 return safe_strdup(
"ErrFingerprint0");
450 if( !mrpgp_calc_fingerprint(mailbox, key, &fingerprint_buf, &fingerprint_bytes) ) {
451 return safe_strdup(
"ErrFingerprint1");
454 char* fingerprint_str = mr_render_fingerprint(fingerprint_buf, fingerprint_bytes);
455 free(fingerprint_buf);
456 return fingerprint_str;
An object representing a single mailbox.