* cryptplug.h, gpgmeplug.c: Added certificate info listing functions.

Not yet complete.
Converted more C99 style comments to "classic" style.
This commit is contained in:
Steffen Hansen 2002-05-30 06:24:19 +00:00
parent 3d05bb406b
commit 068ef9f0f3
3 changed files with 379 additions and 15 deletions

View File

@ -1,3 +1,9 @@
2002-05-30 Steffen Hansen <steffen@hrhansen.dk>
* cryptplug.h, gpgmeplug.c: Added certificate info listing functions.
Not yet complete.
Converted more C99 style comments to "classic" style.
2002-03-23 Werner Koch <wk@gnupg.org>
* gpgmeplug.c: Converted it to real C; i.e. use standard comments -

View File

@ -32,9 +32,6 @@ typedef char bool;
#endif
#include <stdlib.h>
//#include <string.h>
//#include <ctype.h>
/*! \file cryptplug.h
\brief Common API header for CRYPTPLUG.
@ -160,6 +157,9 @@ typedef char bool;
plugin <b>you should ignore this</b> section!
*/
/*! \defgroup certList Certificate Info listing functions
*/
typedef enum {
Feature_undef = 0,
@ -179,10 +179,11 @@ typedef enum {
Feature_StoreMessagesEncrypted = 13,
Feature_CheckCertificatePath = 14,
Feature_CertificateDirectoryService = 15,
Feature_CRLDirectoryService = 16
Feature_CRLDirectoryService = 16,
Feature_CertificateInfo = 17
} Feature;
// dummy values
/* dummy values */
typedef enum {
PinRequest_undef = 0,
@ -193,7 +194,7 @@ typedef enum {
PinRequest_AfterMinutes = 5
} PinRequests;
// dummy values:
/* dummy values: */
typedef enum {
SendCert_undef = 0,
@ -203,7 +204,7 @@ typedef enum {
SendCert_SendChainWithRoot = 4
} SendCertificates;
// dummy values:
/* dummy values: */
typedef enum {
SignAlg_undef = 0,
@ -1212,7 +1213,7 @@ struct StructuringInfo {
FALSE) */
bool makeMimeObject; /*!< specifies whether we should create a MIME
object or a flat text message body */
// the following are used for MIME messages only
/* the following are used for MIME messages only */
bool makeMultiMime; /*!< specifies whether we should create a
'Multipart' MIME object or a single part
object, if FALSE only \c contentTypeMain,
@ -1279,7 +1280,7 @@ struct StructuringInfo {
\c makeMimeObject or \c makeMultiMime
is FALSE or if \c contentTypeCode does
not return a non-zero-length string) */
// the following are used for flat non-MIME messages only
/* the following are used for flat non-MIME messages only */
char* flatTextPrefix; /*!< text to preceed the main text (or the
code bloc containing the encrypted main
text, resp.)<br>
@ -1323,7 +1324,7 @@ struct StructuringInfo {
\see free_StructuringInfo, StructuringInfo
\see signMessage, encryptMessage, encryptAndSignMessage
*/
void init_StructuringInfo( struct StructuringInfo* s )
static void init_StructuringInfo( struct StructuringInfo* s )
{
if( ! s ) return;
@ -1364,7 +1365,7 @@ struct StructuringInfo {
\see StructuringInfo
*/
void free_StructuringInfo( struct StructuringInfo* s )
static void free_StructuringInfo( struct StructuringInfo* s )
{
if( ! s ) return;
if( s->contentTypeMain ) free( s->contentTypeMain );
@ -1691,6 +1692,41 @@ const char* displayCRL( void );
*/
void updateCRL( void );
struct CertIterator;
struct DnPair {
char *key;
char *value;
};
struct CertificateInfo {
char** userid;
char** issuer;
struct DnPair *dnarray;
};
/*! \function struct CertIterator* startListCertificates( void );
\function struct CertificateInfo* nextCertificate( struct CertIterator* );
\function void endListCertificates( struct CertIterator* );
\ingroup certList
Example:
\verbatim
struct CertificateInfo* info;
struct CertIterator* it = startListCertificates();
while( info = nextCertificate( it ) ) {
do something with info.
dont free() it, the struct will be reused
by the next call to nextCertificate()
}
endListCertificates( it );
\endverbatim
*/
struct CertIterator* startListCertificates( void );
struct CertificateInfo* nextCertificate( struct CertIterator* );
void endListCertificates( struct CertIterator* );
#ifdef __cplusplus
}
#endif

View File

@ -249,6 +249,7 @@ bool hasFeature( Feature flag )
case Feature_CheckCertificatePath: return true;
case Feature_CertificateDirectoryService: return true;
case Feature_CRLDirectoryService: return true;
case Feature_CertificateInfo: return true;
/* undefined or not yet implemented: */
case Feature_undef: return false;
default: return false;
@ -452,7 +453,7 @@ bool signatureCertificateExpiryNearWarning( void )
int signatureCertificateDaysLeftToExpiry( const char* certificate )
{
// pending (khz): make this work!
/* pending (khz): make this work! */
/*
GpgmeCtx ctx;
GpgmeError err;
@ -1608,8 +1609,8 @@ bool requestDecentralCertificate( const char* certparms,
}
gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS);
// Don't ASCII-armor, the MUA will use base64 encoding
// gpgme_set_armor (ctx, 1);
/* Don't ASCII-armor, the MUA will use base64 encoding */
/* gpgme_set_armor (ctx, 1); */
err = gpgme_op_genkey (ctx, certparms, pub, NULL );
fprintf( stderr, "3: gpgme returned %d\n", err );
if( err != GPGME_No_Error ) {
@ -1623,7 +1624,7 @@ bool requestDecentralCertificate( const char* certparms,
*length = len;
/* The buffer generatedKey contains the LEN bytes you want */
// Caller is responsible for freeing
/* Caller is responsible for freeing */
return true;
}
@ -1648,3 +1649,324 @@ bool archiveCertificate( const char* certificate ){ return true; }
const char* displayCRL(){ return 0; }
void updateCRL(){}
/*
* Copyright (C) 2002 g10 Code GmbH
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111, USA.
*/
/* some macros to replace ctype ones and avoid locale problems */
#define spacep(p) (*(p) == ' ' || *(p) == '\t')
#define digitp(p) (*(p) >= '0' && *(p) <= '9')
#define hexdigitp(a) (digitp (a) \
|| (*(a) >= 'A' && *(a) <= 'F') \
|| (*(a) >= 'a' && *(a) <= 'f'))
/* the atoi macros assume that the buffer has only valid digits */
#define atoi_1(p) (*(p) - '0' )
#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1))
#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2))
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
#define safe_malloc( x ) malloc( x )
static void safe_free( void** x )
{
free( *x );
*x = 0;
}
/*#define safe_free( x ) free( x )*/
struct dn_array_s {
char *key;
char *value;
};
/* Parse a DN and return an array-ized one. This is not a validating
parser and it does not support any old-stylish syntax; gpgme is
expected to return only rfc2253 compatible strings. */
static const unsigned char *
parse_dn_part (struct dn_array_s *array, const unsigned char *string)
{
const unsigned char *s, *s1;
size_t n;
unsigned char *p;
/* parse attributeType */
for (s = string+1; *s && *s != '='; s++)
;
if (!*s)
return NULL; /* error */
n = s - string;
if (!n)
return NULL; /* empty key */
array->key = p = safe_malloc (n+1);
memcpy (p, string, n); /* fixme: trim trailing spaces */
p[n] = 0;
string = s + 1;
if (*string == '#')
{ /* hexstring */
string++;
for (s=string; hexdigitp (s); s++)
s++;
n = s - string;
if (!n || (n & 1))
return NULL; /* empty or odd number of digits */
n /= 2;
array->value = p = safe_malloc (n+1);
for (s1=string; n; s1 += 2, n--)
*p++ = xtoi_2 (s1);
*p = 0;
}
else
{ /* regular v3 quoted string */
for (n=0, s=string; *s; s++)
{
if (*s == '\\')
{ /* pair */
s++;
if (*s == ',' || *s == '=' || *s == '+'
|| *s == '<' || *s == '>' || *s == '#' || *s == ';'
|| *s == '\\' || *s == '\"' || *s == ' ')
n++;
else if (hexdigitp (s) && hexdigitp (s+1))
{
s++;
n++;
}
else
return NULL; /* invalid escape sequence */
}
else if (*s == '\"')
return NULL; /* invalid encoding */
else if (*s == ',' || *s == '=' || *s == '+'
|| *s == '<' || *s == '>' || *s == '#' || *s == ';' )
break;
else
n++;
}
array->value = p = safe_malloc (n+1);
for (s=string; n; s++, n--)
{
if (*s == '\\')
{
s++;
if (hexdigitp (s))
{
*p++ = xtoi_2 (s);
s++;
}
else
*p++ = *s;
}
else
*p++ = *s;
}
*p = 0;
}
return s;
}
/* Parse a DN and return an array-ized one. This is not a validating
parser and it does not support any old-stylish syntax; gpgme is
expected to return only rfc2253 compatible strings. */
static struct dn_array_s *
parse_dn (const unsigned char *string)
{
struct dn_array_s *array;
size_t arrayidx, arraysize;
int i;
arraysize = 7; /* C,ST,L,O,OU,CN,email */
array = safe_malloc ((arraysize+1) * sizeof *array);
arrayidx = 0;
while (*string)
{
while (*string == ' ')
string++;
if (!*string)
break; /* ready */
if (arrayidx >= arraysize)
{ /* mutt lacks a real safe_realoc - so we need to copy */
struct dn_array_s *a2;
arraysize += 5;
a2 = safe_malloc ((arraysize+1) * sizeof *array);
for (i=0; i < arrayidx; i++)
{
a2[i].key = array[i].key;
a2[i].value = array[i].value;
}
safe_free ((void **)&array);
array = a2;
}
array[arrayidx].key = NULL;
array[arrayidx].value = NULL;
string = parse_dn_part (array+arrayidx, string);
arrayidx++;
if (!string)
goto failure;
while (*string == ' ')
string++;
if (*string && *string != ',' && *string != ';' && *string != '+')
goto failure; /* invalid delimiter */
if (*string)
string++;
}
array[arrayidx].key = NULL;
array[arrayidx].value = NULL;
return array;
failure:
for (i=0; i < arrayidx; i++)
{
safe_free ((void**)&array[i].key);
safe_free ((void**)&array[i].value);
}
safe_free ((void**)&array);
return NULL;
}
struct CertIterator {
GpgmeCtx ctx;
struct CertificateInfo info;
};
struct CertIterator* startListCertificates( void )
{
GpgmeError err;
struct CertIterator* it;
/*fprintf( stderr, "startListCertificates()" );*/
it = (struct CertIterator*)safe_malloc( sizeof( struct CertIterator ) );
err = gpgme_new (&(it->ctx));
/*fprintf( stderr, "2: gpgme returned %d\n", err );*/
if( err != GPGME_No_Error ) {
free( it );
return NULL;
}
gpgme_set_protocol (it->ctx, GPGME_PROTOCOL_CMS);
err = gpgme_op_keylist_start ( it->ctx, NULL, 0);
if( err != GPGME_No_Error ) {
endListCertificates( it );
return NULL;
}
memset( &(it->info), 0, sizeof( struct CertificateInfo ) );
return it;
}
#define MAX_GPGME_IDX 20
static void freeStringArray( char** c )
{
char** _c = c;
while( c && *c ) {
/*fprintf( stderr, "freeing \"%s\"\n", *c );*/
safe_free( (void**)&(*c) );
++c;
}
safe_free( (void**)&_c );
}
static void freeInfo( struct CertificateInfo* info )
{
struct DnPair* a = info->dnarray;
assert( info );
/*fprintf( stderr, "freeing info->userid\n" );*/
if( info->userid ) freeStringArray( info->userid );
/*fprintf( stderr, "freeing info->issuer\n" );*/
if( info->issuer ) freeStringArray( info->issuer );
/*fprintf( stderr, "freed\n" );*/
while( a && a->key && a->value ) {
/*fprintf( stderr, "freeing %s\n", a->key );*/
safe_free ((void**)&(a->key));
safe_free ((void**)&(a->value));
++a;
}
if( info->dnarray ) safe_free ((void**)&(info->dnarray));
memset( info, 0, sizeof( *info ) );
}
#define xstrdup( x ) (x)?strdup(x):0
struct CertificateInfo* nextCertificate( struct CertIterator* it )
{
GpgmeError err;
GpgmeKey key;
assert( it );
err = gpgme_op_keylist_next ( it->ctx, &key);
if( err != GPGME_EOF ) {
int idx;
const char* s;
char* names[MAX_GPGME_IDX+1];
memset( names, 0, sizeof( names ) );
freeInfo( &(it->info) );
for( idx = 0; (s = gpgme_key_get_string_attr (key, GPGME_ATTR_USERID, 0, idx)) && idx < MAX_GPGME_IDX;
++idx ) {
names[idx] = xstrdup( s );
}
it->info.userid = safe_malloc( sizeof( char* ) * (idx+1) );
memset( it->info.userid, 0, sizeof( char* ) * (idx+1) );
it->info.dnarray = 0;
for( idx = 0; names[idx] != 0; ++idx ) {
struct DnPair* a = parse_dn( names[idx] );
it->info.userid[idx] = names[idx];
it->info.dnarray = a;
}
it->info.userid[idx] = 0;
memset( names, 0, sizeof( names ) );
for( idx = 0; (s = gpgme_key_get_string_attr (key, GPGME_ATTR_ISSUER, 0, idx)) && idx < MAX_GPGME_IDX;
++idx ) {
/*fprintf(stderr, "Got issuer \"%s\"\n", s );*/
names[idx] = xstrdup( s );
}
it->info.issuer = safe_malloc( sizeof( char* ) * (idx+1) );
memset( it->info.issuer, 0, sizeof( char* ) * (idx+1) );
for( idx = 0; names[idx] != 0; ++idx ) {
it->info.issuer[idx] = names[idx];
}
it->info.issuer[idx] = 0;
gpgme_key_release (key);
return &(it->info);
} else return NULL;
}
void endListCertificates( struct CertIterator* it )
{
/*fprintf( stderr, "endListCertificates()\n" );*/
assert(it);
freeInfo( &(it->info) );
gpgme_op_keylist_end(it->ctx);
gpgme_release (it->ctx);
free( it );
}