Delta Chat Core C-Library
mrkeyring.c
1 /*******************************************************************************
2  *
3  * Delta Chat Core
4  * Copyright (C) 2017 Björn Petersen
5  * Contact: r10s@b44t.com, http://b44t.com
6  *
7  * This program is free software: you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License as published by the Free Software
9  * Foundation, either version 3 of the License, or (at your option) any later
10  * version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program. If not, see http://www.gnu.org/licenses/ .
19  *
20  ******************************************************************************/
21 
22 
23 #include "mrmailbox_internal.h"
24 #include <memory.h>
25 #include "mrkey.h"
26 #include "mrkeyring.h"
27 #include "mrtools.h"
28 
29 
30 /*******************************************************************************
31  * Main interface
32  ******************************************************************************/
33 
34 
35 mrkeyring_t* mrkeyring_new()
36 {
37  mrkeyring_t* ths;
38 
39  if( (ths=calloc(1, sizeof(mrkeyring_t)))==NULL ) {
40  exit(42); /* cannot allocate little memory, unrecoverable error */
41  }
42  return ths;
43 }
44 
45 
46 void mrkeyring_unref(mrkeyring_t* ths)
47 {
48  int i;
49  if( ths == NULL ) {
50  return;
51  }
52 
53  for( i = 0; i < ths->m_count; i++ ) {
54  mrkey_unref(ths->m_keys[i]);
55  }
56  free(ths->m_keys);
57  free(ths);
58 }
59 
60 
61 void mrkeyring_add(mrkeyring_t* ths, mrkey_t* to_add)
62 {
63  if( ths==NULL || to_add==NULL ) {
64  return;
65  }
66 
67  /* expand array, if needed */
68  if( ths->m_count == ths->m_allocated ) {
69  int newsize = (ths->m_allocated * 2) + 10;
70  if( (ths->m_keys=realloc(ths->m_keys, newsize*sizeof(mrkey_t*)))==NULL ) {
71  exit(41);
72  }
73  ths->m_allocated = newsize;
74  }
75 
76  ths->m_keys[ths->m_count] = mrkey_ref(to_add);
77  ths->m_count++;
78 }
79 
80 
81 int mrkeyring_load_self_private_for_decrypting__(mrkeyring_t* ths, const char* self_addr, mrsqlite3_t* sql)
82 {
83  sqlite3_stmt* stmt;
84  mrkey_t* key;
85 
86  if( ths==NULL || self_addr==NULL || sql==NULL ) {
87  return 0;
88  }
89 
90  stmt = mrsqlite3_predefine__(sql, SELECT_private_key_FROM_keypairs_ORDER_BY_default,
91  "SELECT private_key FROM keypairs ORDER BY addr=? DESC, is_default DESC;");
92  sqlite3_bind_text (stmt, 1, self_addr, -1, SQLITE_STATIC);
93  while( sqlite3_step(stmt) == SQLITE_ROW ) {
94  key = mrkey_new();
95  if( mrkey_set_from_stmt(key, stmt, 0, MR_PRIVATE) ) {
96  mrkeyring_add(ths, key);
97  }
98  mrkey_unref(key); /* unref in any case, mrkeyring_add() adds its own reference */
99  }
100 
101  return 1;
102 }
103