struct DnPair *dnarray; /* parsed values from userid[0] */
};
-/*! \function struct CertIterator* startListCertificates( void );
+/*! \function struct CertIterator* startListCertificates( const char* pattern );
\function struct CertificateInfo* nextCertificate( struct CertIterator* );
\function void endListCertificates( struct CertIterator* );
\ingroup certList
- Example:
+ Example that runs through certs matching "Steffen":
\verbatim
struct CertificateInfo* info;
- struct CertIterator* it = startListCertificates();
+ struct CertIterator* it = startListCertificates("Steffen");
while( info = nextCertificate( it ) ) {
do something with info.
dont free() it, the struct will be reused
endListCertificates( it );
\endverbatim
*/
-struct CertIterator* startListCertificates( void );
+struct CertIterator* startListCertificates( const char* pattern );
struct CertificateInfo* nextCertificate( struct CertIterator* );
void endListCertificates( struct CertIterator* );
* Boston, MA 02111, USA.
*/
+/* Max number of parts in a DN */
+#define MAX_GPGME_IDX 20
+
/* some macros to replace ctype ones and avoid locale problems */
#define spacep(p) (*(p) == ' ' || *(p) == '\t')
#define digitp(p) (*(p) >= '0' && *(p) <= '9')
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
#define safe_malloc( x ) malloc( x )
+#define xstrdup( x ) (x)?strdup(x):0
static void safe_free( void** x )
{
return NULL;
}
+static int add_dn_part( char* result, struct DnPair* dn, const char* part )
+{
+ int any = 0;
+ for(; dn->key; ++dn ) {
+ if( !strcmp( dn->key, part ) ) {
+ if( any ) strcat( result, "+" );
+ strcat( result, dn->value );
+ any = 1;
+ }
+ }
+ return any;
+}
+
+static char* reorder_dn( struct DnPair *dn )
+{
+ const char* stdpart[] = {
+ "CN", "OU", "O", "STREET", "L", "ST", "C", NULL
+ };
+ int any=0, any2=0, len=0, i;
+ char* result;
+ for( i = 0; dn[i].key; ++i ) {
+ len += strlen( dn[i].key );
+ len += strlen( dn[i].value );
+ len += 4; /* ',' and '=', and possibly "(" and ")" */
+ }
+ result = (char*)safe_malloc( (len+1)*sizeof(char) );
+ *result = 0;
+
+ /* add standard parts */
+ for( i = 0; stdpart[i]; ++i ) {
+ if( any ) {
+ strcat( result, "," );
+ }
+ any = add_dn_part( result, dn, stdpart[i] );
+ }
+
+ /* add remaining parts in no particular order */
+ for(; dn->key; ++dn ) {
+ for( i = 0; stdpart[i]; ++i ) {
+ if( !strcmp( dn->key, stdpart[i] ) ) {
+ break;
+ }
+ }
+ if( !stdpart[i] ) {
+ if( any ) strcat( result, "," );
+ if( !any2 ) strcat( result, "(");
+ any = add_dn_part( result, dn, dn->key );
+ any2 = 1;
+ }
+ }
+ if( any2 ) strcat( result, ")");
+ return result;
+}
struct CertIterator {
GpgmeCtx ctx;
struct CertificateInfo info;
};
-struct CertIterator* startListCertificates( void )
+struct CertIterator* startListCertificates( const char* pattern )
{
GpgmeError err;
struct CertIterator* it;
}
gpgme_set_protocol (it->ctx, GPGME_PROTOCOL_CMS);
- err = gpgme_op_keylist_start ( it->ctx, NULL, 0);
+ err = gpgme_op_keylist_start ( it->ctx, pattern, 0);
if( err != GPGME_No_Error ) {
endListCertificates( it );
return NULL;
return it;
}
-#define MAX_GPGME_IDX 20
-
static void freeStringArray( char** c )
{
char** _c = c;
memset( info, 0, sizeof( *info ) );
}
-#define xstrdup( x ) (x)?strdup(x):0
+static char* make_fingerprint( const char* fpr )
+{
+ int len = strlen(fpr);
+ int i = 0;
+ char* result = safe_malloc( (len + len/2 + 1)*sizeof(char) );
+ if( !result ) return NULL;
+ for(; *fpr; ++fpr, ++i ) {
+ if( i%3 == 2) {
+ result[i] = ':'; ++i;
+ }
+ result[i] = *fpr;
+ }
+ result[i] = 0;
+ return result;
+}
struct CertificateInfo* nextCertificate( struct CertIterator* it )
{
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;
+ if( idx == 0 ) {
+ it->info.userid[idx] = reorder_dn( a );
+ safe_free( &(names[idx]) );
+ } else {
+ it->info.userid[idx] = names[idx];
+ it->info.dnarray = a;
+ }
}
it->info.userid[idx] = 0;
it->info.serial = xstrdup(s);
s = gpgme_key_get_string_attr (key, GPGME_ATTR_FPR, 0, 0);
- it->info.fingerprint = xstrdup(s);
+ it->info.fingerprint = make_fingerprint( s );
s = gpgme_key_get_string_attr (key, GPGME_ATTR_ISSUER, 0, 0);
it->info.issuer = xstrdup(s);