1
/* fingerprint.c - Get the fingerprint
2
* Copyright (C) 2001 Free Software Foundation, Inc.
4
* This file is part of GnuPG.
6
* GnuPG is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* GnuPG is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
35
/* Return the fingerprint of the certificate (we can't put this into
36
libksba because we need libgcrypt support). The caller must
37
provide an array of sufficient length or NULL so that the function
38
allocates the array. If r_len is not NULL, the length of the
39
digest is returned; well, this can also be done by using
40
gcry_md_get_algo_dlen(). If algo is 0, a SHA-1 will be used.
42
If there is a problem , the function does never return NULL but a
46
gpgsm_get_fingerprint (ksba_cert_t cert, int algo, char *array, int *r_len)
54
len = gcry_md_get_algo_dlen (algo);
57
array = xmalloc (len);
62
rc = gcry_md_open (&md, algo, 0);
65
log_error ("md_open failed: %s\n", gpg_strerror (rc));
66
memset (array, 0xff, len); /* better return an invalid fpr than NULL */
70
rc = ksba_cert_hash (cert, 0, HASH_FNC, md);
73
log_error ("ksba_cert_hash failed: %s\n", gpg_strerror (rc));
75
memset (array, 0xff, len); /* better return an invalid fpr than NULL */
79
memcpy (array, gcry_md_read(md, algo), len );
84
/* Return an allocated buffer with the formatted fingerprint */
86
gpgsm_get_fingerprint_string (ksba_cert_t cert, int algo)
88
unsigned char digest[MAX_DIGEST_LEN];
95
len = gcry_md_get_algo_dlen (algo);
96
assert (len <= MAX_DIGEST_LEN );
97
gpgsm_get_fingerprint (cert, algo, digest, NULL);
98
buf = xmalloc (len*3+1);
100
for (i=0; i < len; i++ )
101
sprintf (buf+strlen(buf), i? ":%02X":"%02X", digest[i]);
105
/* Return an allocated buffer with the formatted fingerprint as one
108
gpgsm_get_fingerprint_hexstring (ksba_cert_t cert, int algo)
110
unsigned char digest[MAX_DIGEST_LEN];
117
len = gcry_md_get_algo_dlen (algo);
118
assert (len <= MAX_DIGEST_LEN );
119
gpgsm_get_fingerprint (cert, algo, digest, NULL);
120
buf = xmalloc (len*3+1);
122
for (i=0; i < len; i++ )
123
sprintf (buf+strlen(buf), "%02X", digest[i]);
127
/* Return a certificate ID. These are the last 4 bytes of the SHA-1
130
gpgsm_get_short_fingerprint (ksba_cert_t cert)
132
unsigned char digest[20];
134
gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL);
135
return ((digest[16]<<24)|(digest[17]<<16)|(digest[18]<< 8)|digest[19]);
139
/* Return the so called KEYGRIP which is the SHA-1 hash of the public
140
key parameters expressed as an canoncial encoded S-Exp. array must
141
be 20 bytes long. returns the array or a newly allocated one if the
142
passed one was NULL */
144
gpgsm_get_keygrip (ksba_cert_t cert, char *array)
151
p = ksba_cert_get_public_key (cert);
153
return NULL; /* oops */
156
log_debug ("get_keygrip for public key\n");
157
n = gcry_sexp_canon_len (p, 0, NULL, NULL);
160
log_error ("libksba did not return a proper S-Exp\n");
163
rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n);
167
log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
170
array = gcry_pk_get_keygrip (s_pkey, array);
171
gcry_sexp_release (s_pkey);
174
rc = gpg_error (GPG_ERR_GENERAL);
175
log_error ("can't calculate keygrip\n");
179
log_printhex ("keygrip=", array, 20);
184
/* Return an allocated buffer with the keygrip of CERT in from of an
185
hexstring. NULL is returned in case of error */
187
gpgsm_get_keygrip_hexstring (ksba_cert_t cert)
189
unsigned char grip[20];
193
gpgsm_get_keygrip (cert, grip);
194
buf = p = xmalloc (20*2+1);
195
for (i=0; i < 20; i++, p += 2 )
196
sprintf (p, "%02X", grip[i]);
201
/* Return the PK algorithm used by CERT as well as the length in bits
202
of the public key at NBITS. */
204
gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits)
217
p = ksba_cert_get_public_key (cert);
220
n = gcry_sexp_canon_len (p, 0, NULL, NULL);
226
rc = gcry_sexp_sscan (&s_pkey, NULL, p, n);
232
*nbits = gcry_pk_get_nbits (s_pkey);
234
/* Breaking the algorithm out of the S-exp is a bit of a challenge ... */
235
l1 = gcry_sexp_find_token (s_pkey, "public-key", 0);
238
gcry_sexp_release (s_pkey);
241
l2 = gcry_sexp_cadr (l1);
242
gcry_sexp_release (l1);
244
name = gcry_sexp_nth_data (l1, 0, &n);
247
if (n > sizeof namebuf -1)
248
n = sizeof namebuf -1;
249
memcpy (namebuf, name, n);
254
gcry_sexp_release (l1);
255
gcry_sexp_release (s_pkey);
256
return gcry_pk_map_name (namebuf);
262
/* For certain purposes we need a certificate id which has an upper
263
limit of the size. We use the hash of the issuer name and the
264
serial number for this. In most cases the serial number is not
265
that large and the resulting string can be passed on an assuan
266
command line. Everything is hexencoded with the serialnumber
267
delimited from the hash by a dot.
269
The caller must free the string.
272
gpgsm_get_certid (ksba_cert_t cert)
277
unsigned char hash[20];
282
p = ksba_cert_get_issuer (cert, 0);
284
return NULL; /* Ooops: No issuer */
285
gcry_md_hash_buffer (GCRY_MD_SHA1, hash, p, strlen (p));
288
serial = ksba_cert_get_serial (cert);
290
return NULL; /* oops: no serial number */
294
log_error ("Ooops: invalid serial number\n");
299
n = strtoul (p, &endp, 10);
303
log_error ("Ooops: invalid serial number (no colon)\n");
309
certid = xtrymalloc ( 40 + 1 + n*2 + 1);
313
return NULL; /* out of core */
316
for (i=0, endp = certid; i < 20; i++, endp += 2 )
317
sprintf (endp, "%02X", hash[i]);
319
for (i=0; i < n; i++, endp += 2)
320
sprintf (endp, "%02X", p[i]);