~ubuntu-branches/ubuntu/maverick/gnutls26/maverick-updates

« back to all changes in this revision

Viewing changes to lib/opencdk/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Metzler
  • Date: 2009-04-14 14:23:19 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20090414142319-ok7xejzbqkofno1q
Tags: 2.6.5-1
* Sync sections in debian/control with override file. libgnutls26-dbg is
  section debug, guile-gnutls is section lisp.
* New upstream version. (Needed for Libtasn1-3 2.0)
* New patch 15_tasn1inpc.diff. Make sure libtasn1 is listed in Libs.private.
* Standards-Version: 3.8.1, no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
/* Set a default cipher algorithm and a digest algorithm.
42
42
   Even if AES and SHA-256 are not 'MUST' in the latest
43
43
   OpenPGP draft, AES seems to be a good choice. */
44
 
#define DEFAULT_CIPHER_ALGO GCRY_CIPHER_AES
45
 
#define DEFAULT_DIGEST_ALGO GCRY_MD_SHA256
46
 
 
47
 
/* The site of the secure memory which is allocated in gcrypt. */
48
 
#define SECMEM_SIZE 16384
49
 
 
50
 
 
51
 
/* Hooks to custom memory allocation functions. */
52
 
static void *(*alloc_func) (size_t n) = gcry_xmalloc;
53
 
static void *(*alloc_secure_func) (size_t n) = gcry_malloc_secure;
54
 
static void *(*realloc_func) (void *p, size_t n) = gcry_realloc;
55
 
static void *(*calloc_func) (size_t m, size_t n) = gcry_calloc;
56
 
static void (*free_func) (void *) = gcry_free;
57
 
static int malloc_hooks = 0;
58
 
static int secmem_init = 0;
59
 
 
60
 
/* Global settings for the logging. */
61
 
static cdk_log_fnc_t log_handler = NULL;
62
 
static void *log_handler_value = NULL;
63
 
static int log_level = CDK_LOG_NONE;
64
 
 
65
 
 
66
 
/**
67
 
 * cdk_strerror:
68
 
 * @ec: the error number
69
 
 *
70
 
 * Return an error text for the given id.
71
 
 **/
72
 
const char*
73
 
cdk_strerror (int ec)
74
 
{
75
 
  static char buf[20];
76
 
  
77
 
  switch (ec) 
78
 
    {
79
 
    case CDK_EOF:              return "End Of File";
80
 
    case CDK_Success:          return "No error";
81
 
    case CDK_General_Error:    return "General error";
82
 
    case CDK_File_Error:       return strerror (errno);
83
 
    case CDK_Bad_Sig:          return "Bad signature";
84
 
    case CDK_Inv_Packet:       return "Invalid packet";
85
 
    case CDK_Inv_Algo:         return "Invalid algorithm";
86
 
    case CDK_Not_Implemented:  return "This is not implemented yet";
87
 
    case CDK_Armor_Error:      return "ASCII armor error";
88
 
    case CDK_Armor_CRC_Error:  return "ASCII armored damaged (CRC error)";
89
 
    case CDK_MPI_Error:        return "Invalid or missformed MPI";
90
 
    case CDK_Inv_Value:        return "Invalid parameter or value";
91
 
    case CDK_Error_No_Key:     return "No key available or not found";
92
 
    case CDK_Chksum_Error:     return "Check for key does not match";
93
 
    case CDK_Time_Conflict:    return "Time conflict";
94
 
    case CDK_Zlib_Error:       return "ZLIB error";
95
 
    case CDK_Weak_Key:         return "Weak key was detected";
96
 
    case CDK_Out_Of_Core:      return "Out of core!!";
97
 
    case CDK_Wrong_Seckey:     return "Wrong secret key";
98
 
    case CDK_Wrong_Format:     return "Data has wrong format";
99
 
    case CDK_Bad_MDC:          return "Manipulated MDC detected";
100
 
    case CDK_Inv_Mode:         return "Invalid mode";
101
 
    case CDK_Error_No_Keyring: return "No keyring available";
102
 
    case CDK_Inv_Packet_Ver:   return "Invalid version for packet";
103
 
    case CDK_Too_Short:        return "Buffer or object is too short";
104
 
    case CDK_Unusable_Key:     return "Unusable public key";
105
 
    case CDK_No_Data:          return "No data";
106
 
    case CDK_No_Passphrase:    return "No passphrase supplied";
107
 
    case CDK_Network_Error:    return "A network error occurred";
108
 
    default:                   sprintf (buf, "ec=%d", ec); return buf;
109
 
    }
110
 
  return NULL;
111
 
}
112
 
 
113
 
 
114
 
static void
115
 
out_of_core (size_t n)
116
 
{
117
 
  fprintf (stderr, "\n ** fatal error: out of memory (%d bytes) **\n", n);
118
 
}
119
 
 
120
 
 
121
 
/**
122
 
 * cdk_set_malloc_hooks: 
123
 
 * @new_alloc_func: malloc replacement
124
 
 * @new_alloc_secure_func: secure malloc replacement
125
 
 * @new_realloc_func: realloc replacement
126
 
 * @new_calloc_func: calloc replacement
127
 
 * @new_free_func: free replacement
128
 
 *
129
 
 * Set private memory hooks for the library.
130
 
 */
131
 
void
132
 
cdk_set_malloc_hooks (void *(*new_alloc_func) (size_t n),
133
 
                      void *(*new_alloc_secure_func) (size_t n),
134
 
                      void *(*new_realloc_func) (void *p, size_t n),
135
 
                      void *(*new_calloc_func) (size_t m, size_t n),
136
 
                      void (*new_free_func) (void *))
137
 
{
138
 
  alloc_func = new_alloc_func;
139
 
  alloc_secure_func = new_alloc_secure_func;
140
 
  realloc_func = new_realloc_func;
141
 
  calloc_func = new_calloc_func;
142
 
  free_func = new_free_func;
143
 
  malloc_hooks = 1;
144
 
}
145
 
 
146
 
 
147
 
/**
148
 
 * cdk_malloc_hook_initialized:
149
 
 *
150
 
 * Return if the malloc hooks are already initialized.
151
 
 **/
152
 
int
153
 
cdk_malloc_hook_initialized (void)
154
 
{
155
 
  return malloc_hooks;
156
 
}
157
 
 
158
 
 
159
 
void*
160
 
cdk_malloc (size_t size)
161
 
{
162
 
  void *p = alloc_func (size);
163
 
  if (!p)
164
 
    out_of_core (size);
165
 
  return p;
166
 
}
167
 
 
168
 
 
169
 
/**
170
 
 * cdk_calloc:
171
 
 * @n: amount of elements
172
 
 * @m: size of one element
173
 
 * 
174
 
 * Safe wrapper around the c-function calloc.
175
 
 **/
176
 
void*
177
 
cdk_calloc (size_t n, size_t m)
178
 
{
179
 
  void * p = calloc_func (n, m);
180
 
  if (!p)
181
 
    out_of_core (m);
182
 
  return p;
183
 
}
184
 
 
185
 
 
186
 
/* Things which need to  be done after the secure memory initialisation. */
187
 
static void
188
 
_secmem_finish (void)
189
 
{
190
 
  gcry_control (GCRYCTL_DROP_PRIVS);
191
 
}
192
 
 
193
 
 
194
 
/* Initialize the secure memory. */
195
 
static void
196
 
_secmem_init (size_t size)
197
 
{
198
 
  if (secmem_init == 1)
199
 
    return;
200
 
  if (size >= SECMEM_SIZE)
201
 
    size = SECMEM_SIZE;
202
 
  
203
 
  /* Check if no other library has already initialized gcrypt. */
204
 
  if (!gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
205
 
    {
206
 
      _cdk_log_debug ("init: libgcrypt initialize.\n");
207
 
      gcry_control (GCRYCTL_INIT_SECMEM, size, 0);
208
 
      gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
209
 
      gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);      
210
 
      gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
211
 
      secmem_init = 1;
212
 
    }  
213
 
}
214
 
 
215
 
 
216
 
/* Things which needs to be done to deinit the secure memory. */
217
 
static void
218
 
_secmem_end (void)
219
 
{
220
 
  gcry_control (GCRYCTL_TERM_SECMEM);
221
 
  secmem_init = 0;
222
 
}
223
 
 
224
 
 
225
 
/* The Windows system needs to startup the Winsock interface first
226
 
   before we can use any socket related function. */
227
 
#ifdef _WIN32
228
 
static void
229
 
init_sockets (void)
230
 
{
231
 
  static int initialized = 0;
232
 
  WSADATA wsdata;
233
 
  
234
 
  if (initialized)
235
 
    return;
236
 
  if (WSAStartup (0x202, &wsdata))
237
 
    _cdk_log_debug ("winsock init failed.\n");
238
 
  
239
 
  initialized = 1;
240
 
}
241
 
 
242
 
static void
243
 
deinit_sockets (void)
244
 
{
245
 
  WSACleanup ();
246
 
}
247
 
#else
248
 
void init_sockets (void)  {}
249
 
void deinit_sockets (void)  {}
250
 
#endif
251
 
 
252
 
 
253
 
/**
254
 
 * cdk_lib_startup:
255
 
 * 
256
 
 * Prepare the internal structures of the library.
257
 
 * This function should be called before any other CDK function.
258
 
 */
259
 
void
260
 
cdk_lib_startup (void)
261
 
{
262
 
  _secmem_init (SECMEM_SIZE);
263
 
  _secmem_finish ();
264
 
  init_sockets ();
265
 
}
266
 
 
267
 
 
268
 
/**
269
 
 * cdk_lib_shutdown:
270
 
 * 
271
 
 * Shutdown the library and free all internal and globally used
272
 
 * memory and structures. This function should be called in the
273
 
 * exit handler of the calling program.
274
 
 */
275
 
void
276
 
cdk_lib_shutdown (void)
277
 
{
278
 
  deinit_sockets ();
279
 
  _secmem_end ();
280
 
}
281
 
 
282
 
/**
283
 
 * cdk_salloc:
284
 
 * @size: how much bytes should be allocated.
285
 
 * @clear: shall the buffer cleared after the allocation?
286
 
 * 
287
 
 * Allocated the requested amount of bytes in 'secure' memory.
288
 
 */
289
 
void*
290
 
cdk_salloc (size_t size, int clear)
291
 
{
292
 
  void *p;
293
 
  
294
 
  if (!secmem_init)
295
 
    _secmem_init (SECMEM_SIZE);
296
 
  
297
 
  p = alloc_secure_func (size);
298
 
  if (!p)
299
 
    out_of_core (size);
300
 
  if (clear)
301
 
    memset (p, 0, size);
302
 
  return p;
303
 
}
304
 
 
305
 
 
306
 
void *
307
 
cdk_realloc (void *ptr, size_t size)
308
 
{
309
 
  void * p = realloc_func (ptr, size);
310
 
  if (!p)
311
 
    out_of_core (size);
312
 
  return p;
313
 
}
314
 
 
315
 
 
316
 
char *
317
 
cdk_strdup (const char * ptr)
318
 
{
319
 
  char * p = cdk_malloc (strlen (ptr) + 1);
320
 
  if (p)
321
 
    strcpy (p, ptr);
322
 
  return p;
323
 
}
324
 
 
325
 
 
326
 
void
327
 
cdk_free (void * ptr)
328
 
{
329
 
  if (ptr)
330
 
    free_func (ptr);
331
 
}
332
 
 
333
 
 
334
 
/* Internal logging routine. */
335
 
static void
336
 
_cdk_logv (int level, const char *fmt, va_list arg_ptr)
337
 
{
338
 
 
339
 
  if (log_handler)
340
 
    log_handler (log_handler_value, level, fmt, arg_ptr);
341
 
  else 
342
 
    {
343
 
      if (level == CDK_LOG_NONE)
344
 
        return;
345
 
      if (level == CDK_LOG_DEBUG)
346
 
        fputs ("DBG: ", stderr);
347
 
      vfprintf (stderr, fmt, arg_ptr); 
348
 
    }
349
 
}
350
 
 
351
 
 
352
 
/**
353
 
 * cdk_set_log_handler: 
354
 
 * @logfnc: the function pointer
355
 
 * @opaque: a private values for the function
356
 
 *
357
 
 * Set a custom handler for logging.
358
 
 **/
359
 
void
360
 
cdk_set_log_handler (cdk_log_fnc_t logfnc, void *opaque)
361
 
{
362
 
  log_handler = logfnc;
363
 
  log_handler_value = opaque; 
364
 
}
365
 
 
366
 
 
367
 
/**
368
 
 * cdk_set_log_level: 
369
 
 * @lvl: the level
370
 
 *
371
 
 * Set the verbosity level.
372
 
 **/
373
 
void
374
 
cdk_set_log_level (int level)
375
 
{
376
 
  log_level = level;
377
 
}
378
 
 
379
 
 
380
 
/* Return the current log level of the lib. */
381
 
int
382
 
_cdk_get_log_level (void)
383
 
{
384
 
  return log_level;
385
 
}
386
 
 
387
 
 
388
 
void
389
 
_cdk_log_info (const char *fmt, ...)
390
 
{
391
 
  va_list arg;
392
 
  
393
 
  if (log_level == CDK_LOG_NONE)
394
 
    return;
395
 
  va_start (arg, fmt);
396
 
  _cdk_logv (CDK_LOG_INFO, fmt, arg);
397
 
  va_end (arg);
398
 
}
399
 
 
400
 
 
401
 
void
402
 
_cdk_log_debug (const char *fmt, ...)
403
 
{
404
 
  va_list arg;
405
 
  
406
 
  if (log_level < CDK_LOG_DEBUG)
407
 
    return;
408
 
  va_start (arg, fmt);
409
 
  _cdk_logv (CDK_LOG_DEBUG, fmt, arg);
410
 
  va_end (arg);
411
 
}
412
 
 
 
44
#define DEFAULT_DIGEST_ALGO GNUTLS_DIG_SHA256
413
45
 
414
46
/* Use the passphrase callback in the handle HD or
415
47
   return NULL if there is no valid callback. */
416
 
char*
 
48
char *
417
49
_cdk_passphrase_get (cdk_ctx_t hd, const char *prompt)
418
50
{
419
51
  if (!hd || !hd->passphrase_cb)
423
55
 
424
56
 
425
57
static void
426
 
handle_set_cipher (cdk_ctx_t hd, int cipher)
427
 
{
428
 
  if (!hd)
429
 
    return;
430
 
  if (gcry_cipher_test_algo (cipher))
431
 
    cipher = DEFAULT_CIPHER_ALGO;
432
 
  hd->cipher_algo = cipher;   
433
 
}
434
 
 
435
 
 
436
 
static void
437
58
handle_set_digest (cdk_ctx_t hd, int digest)
438
59
{
439
60
  if (!hd)
440
61
    return;
441
 
  if (gcry_md_test_algo (digest))
 
62
  if (_gnutls_hash_get_algo_len (digest) <= 0)
442
63
    digest = DEFAULT_DIGEST_ALGO;
443
 
  hd->digest_algo = digest;   
 
64
  hd->digest_algo = digest;
444
65
}
445
66
 
446
67
 
447
68
static void
448
 
handle_set_s2k (cdk_ctx_t hd, int mode, int digest, int cipher)
 
69
handle_set_s2k (cdk_ctx_t hd, int mode, int digest)
449
70
{
450
71
  if (!hd)
451
72
    return;
452
 
  if (gcry_cipher_test_algo (cipher))
453
 
    cipher = DEFAULT_CIPHER_ALGO;
454
 
  if (gcry_md_test_algo (digest))
 
73
  if (_gnutls_hash_get_algo_len (digest) <= 0)
455
74
    digest = DEFAULT_DIGEST_ALGO;
456
75
  if (mode != CDK_S2K_SIMPLE &&
457
 
      mode != CDK_S2K_SALTED &&
458
 
      mode != CDK_S2K_ITERSALTED)
 
76
      mode != CDK_S2K_SALTED && mode != CDK_S2K_ITERSALTED)
459
77
    mode = CDK_S2K_ITERSALTED;
460
78
  hd->_s2k.mode = mode;
461
79
  hd->_s2k.digest_algo = digest;
472
90
  hd->compress.algo = algo;
473
91
  if (!algo)
474
92
    hd->opt.compress = 0;
475
 
  else 
 
93
  else
476
94
    {
477
95
      if (level > 0 && level < 10)
478
96
        hd->compress.level = level;
495
113
{
496
114
  va_list arg_ptr;
497
115
  int set = action == CDK_CTLF_SET, val = 0;
498
 
  
 
116
 
499
117
  if (!hd)
500
118
    return -1;
501
 
  
 
119
 
502
120
  if (action != CDK_CTLF_SET && action != CDK_CTLF_GET)
503
121
    return -1;
504
122
  va_start (arg_ptr, cmd);
505
 
  switch( cmd ) 
 
123
  switch (cmd)
506
124
    {
507
125
    case CDK_CTL_ARMOR:
508
126
      if (set)
509
 
        hd->opt.armor = va_arg( arg_ptr, int );
 
127
        hd->opt.armor = va_arg (arg_ptr, int);
510
128
      else
511
129
        val = hd->opt.armor;
512
130
      break;
513
131
 
514
 
    case CDK_CTL_CIPHER:
515
 
      if (set)
516
 
        handle_set_cipher (hd, va_arg (arg_ptr, int));
517
 
      else
518
 
        val = hd->cipher_algo;
519
 
      break;
520
 
      
521
132
    case CDK_CTL_DIGEST:
522
133
      if (set)
523
 
        handle_set_digest( hd, va_arg( arg_ptr, int ) );
 
134
        handle_set_digest (hd, va_arg (arg_ptr, int));
524
135
      else
525
136
        val = hd->digest_algo;
526
137
      break;
527
 
      
 
138
 
528
139
    case CDK_CTL_OVERWRITE:
529
140
      if (set)
530
141
        hd->opt.overwrite = va_arg (arg_ptr, int);
531
142
      else
532
143
        val = hd->opt.overwrite;
533
144
      break;
534
 
      
 
145
 
535
146
    case CDK_CTL_COMPRESS:
536
 
      if (set) 
 
147
      if (set)
537
148
        {
538
149
          int algo = va_arg (arg_ptr, int);
539
150
          int level = va_arg (arg_ptr, int);
542
153
      else
543
154
        val = hd->compress.algo;
544
155
      break;
545
 
      
 
156
 
546
157
    case CDK_CTL_S2K:
547
 
      if( set ) {
548
 
        int mode = va_arg( arg_ptr, int );
549
 
        int digest = va_arg( arg_ptr, int );
550
 
        int cipher = va_arg( arg_ptr, int );
551
 
        handle_set_s2k( hd, mode, digest, cipher );
552
 
      }
 
158
      if (set)
 
159
        {
 
160
          int mode = va_arg (arg_ptr, int);
 
161
          int digest = va_arg (arg_ptr, int);
 
162
          handle_set_s2k (hd, mode, digest);
 
163
        }
553
164
      else
554
165
        val = hd->_s2k.mode;
555
166
      break;
556
 
      
 
167
 
557
168
    case CDK_CTL_FORCE_DIGEST:
558
169
      if (set)
559
170
        hd->opt.force_digest = va_arg (arg_ptr, int);
560
171
      else
561
172
        val = hd->opt.force_digest;
562
173
      break;
563
 
      
 
174
 
564
175
    case CDK_CTL_BLOCKMODE_ON:
565
 
      if( set )
566
 
        hd->opt.blockmode = va_arg( arg_ptr, int );
 
176
      if (set)
 
177
        hd->opt.blockmode = va_arg (arg_ptr, int);
567
178
      else
568
179
        val = hd->opt.blockmode;
569
180
      break;
570
 
      
 
181
 
571
182
    default:
572
183
      val = -1;
573
 
          break;
 
184
      break;
574
185
    }
575
186
  va_end (arg_ptr);
576
187
  return val;
577
188
}
578
189
 
579
 
            
 
190
 
580
191
 
581
192
/**
582
193
 * cdk_handle_new:
585
196
 * create a new session handle.
586
197
 **/
587
198
cdk_error_t
588
 
cdk_handle_new (cdk_ctx_t *r_ctx)
 
199
cdk_handle_new (cdk_ctx_t * r_ctx)
589
200
{
590
201
  cdk_ctx_t c;
591
 
  
 
202
 
592
203
  if (!r_ctx)
593
204
    return CDK_Inv_Value;
594
 
  
 
205
 
595
206
  c = cdk_calloc (1, sizeof *c);
596
207
  if (!c)
597
208
    return CDK_Out_Of_Core;
598
 
  
 
209
 
599
210
  /* For S2K use the iterated and salted mode and use the
600
211
     default digest and cipher algorithms. Because the MDC
601
212
     feature will be used, the default cipher should use a 
602
213
     blocksize of 128 bits. */
603
214
  c->_s2k.mode = CDK_S2K_ITERSALTED;
604
215
  c->_s2k.digest_algo = DEFAULT_DIGEST_ALGO;
605
 
  
 
216
 
606
217
  c->opt.mdc = 1;
607
218
  c->opt.compress = 1;
608
219
  c->opt.armor = 0;
609
220
  c->opt.textmode = 0;
610
 
  
 
221
 
611
222
  c->digest_algo = DEFAULT_DIGEST_ALGO;
612
 
  c->cipher_algo = DEFAULT_CIPHER_ALGO;
613
 
  
 
223
 
614
224
  c->compress.algo = CDK_COMPRESS_ZIP;
615
225
  c->compress.level = 6;
616
226
 
632
242
{
633
243
  cdk_keydb_hd_t db;
634
244
  cdk_error_t err;
635
 
  
 
245
 
636
246
  err = cdk_keydb_new_from_file (&db, type, kringname);
637
247
  if (err)
638
248
    return err;
639
 
  
 
249
 
640
250
  if (!type)
641
251
    hd->db.pub = db;
642
252
  else
645
255
  return 0;
646
256
}
647
257
 
648
 
  
 
258
 
649
259
/**
650
260
 * cdk_handle_set_keydb:
651
261
 * @hd: session handle
696
306
 *
697
307
 * set the passphrase callback.
698
308
 **/
699
 
void cdk_handle_set_passphrase_cb (cdk_ctx_t hd,
700
 
                                   char *(*cb) (void *opa, const char *prompt),
701
 
                                   void * cb_value)
 
309
void
 
310
cdk_handle_set_passphrase_cb (cdk_ctx_t hd,
 
311
                              char *(*cb) (void *opa, const char *prompt),
 
312
                              void *cb_value)
702
313
{
703
 
    if (!hd)
704
 
        return;
705
 
    hd->passphrase_cb = cb;
706
 
    hd->passphrase_cb_value = cb_value;
 
314
  if (!hd)
 
315
    return;
 
316
  hd->passphrase_cb = cb;
 
317
  hd->passphrase_cb_value = cb_value;
707
318
}
708
319
 
709
320
 
714
325
 * Return the verify result for the current session.
715
326
 * Do not free the pointer.
716
327
 **/
717
 
cdk_verify_result_t 
 
328
cdk_verify_result_t
718
329
cdk_handle_verify_get_result (cdk_ctx_t hd)
719
330
{
720
331
  return hd->result.verify;
743
354
      if (hd->db.sec)
744
355
        cdk_keydb_free (hd->db.sec);
745
356
      hd->db.pub = hd->db.sec = NULL;
746
 
    }  
747
 
  cdk_free (hd->dek);
 
357
    }
748
358
  cdk_free (hd);
749
359
}