aboutsummaryrefslogtreecommitdiffstats
path: root/scd
diff options
context:
space:
mode:
Diffstat (limited to 'scd')
-rw-r--r--scd/ChangeLog8
-rw-r--r--scd/app-p15.c30
-rw-r--r--scd/scdaemon.h12
3 files changed, 42 insertions, 8 deletions
diff --git a/scd/ChangeLog b/scd/ChangeLog
index df9e75a4f..f637e5ad8 100644
--- a/scd/ChangeLog
+++ b/scd/ChangeLog
@@ -1,3 +1,11 @@
+2006-10-24 Werner Koch <[email protected]>
+
+ * scdaemon.h (GCRY_MD_USER_TLS_MD5SHA1): New.
+ (MAX_DIGEST_LEN): Increased to 36.
+ * app-p15.c (do_sign): Support for TLS_MD5SHA1.
+ (do_auth): Detect TLS_MD5SHA1.
+ (do_sign): Tweaks for that digest.
+
2006-10-23 Werner Koch <[email protected]>
* scdaemon.c (main): New command --gpgconf-test.
diff --git a/scd/app-p15.c b/scd/app-p15.c
index f6b3eff4d..f11de5902 100644
--- a/scd/app-p15.c
+++ b/scd/app-p15.c
@@ -2868,8 +2868,9 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
gpg_error_t err;
int i;
- unsigned char data[35]; /* Must be large enough for a SHA-1 digest
- + the largest OID prefix above. */
+ unsigned char data[36]; /* Must be large enough for a SHA-1 digest
+ + the largest OID prefix above and also
+ fit the 36 bytes of md5sha1. */
prkdf_object_t prkdf; /* The private key object. */
aodf_object_t aodf; /* The associated authentication object. */
int no_data_padding = 0; /* True if the card want the data without padding.*/
@@ -2877,7 +2878,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
if (!keyidstr || !*keyidstr)
return gpg_error (GPG_ERR_INV_VALUE);
- if (indatalen != 20 && indatalen != 16 && indatalen != 35)
+ if (indatalen != 20 && indatalen != 16 && indatalen != 35 && indatalen != 36)
return gpg_error (GPG_ERR_INV_VALUE);
err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf);
@@ -2948,7 +2949,10 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
mse[0] = 4; /* Length of the template. */
mse[1] = 0x80; /* Algorithm reference tag. */
- mse[2] = 0x02; /* Algorithm: RSASSA-PKCS1-v1.5 using SHA1. */
+ if (hashalgo == GCRY_MD_USER_TLS_MD5SHA1)
+ mse[2] = 0x01; /* Let card do pkcs#1 0xFF padding. */
+ else
+ mse[2] = 0x02; /* RSASSA-PKCS1-v1.5 using SHA1. */
mse[3] = 0x84; /* Private key reference tag. */
mse[4] = prkdf->key_reference_valid? prkdf->key_reference : 0x82;
@@ -3118,7 +3122,14 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
}
/* Prepare the DER object from INDATA. */
- if (indatalen == 35)
+ if (indatalen == 36)
+ {
+ /* No ASN.1 container used. */
+ if (hashalgo != GCRY_MD_USER_TLS_MD5SHA1)
+ return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
+ memcpy (data, indata, indatalen);
+ }
+ else if (indatalen == 35)
{
/* Alright, the caller was so kind to send us an already
prepared DER object. Check that it is what we want and that
@@ -3177,7 +3188,9 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
return err;
}
- if (no_data_padding)
+ if (hashalgo == GCRY_MD_USER_TLS_MD5SHA1)
+ err = iso7816_compute_ds (app->slot, data, 36, outdata, outdatalen);
+ else if (no_data_padding)
err = iso7816_compute_ds (app->slot, data+15, 20, outdata, outdatalen);
else
err = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
@@ -3200,6 +3213,7 @@ do_auth (app_t app, const char *keyidstr,
{
gpg_error_t err;
prkdf_object_t prkdf;
+ int algo;
if (!keyidstr || !*keyidstr)
return gpg_error (GPG_ERR_INV_VALUE);
@@ -3212,7 +3226,9 @@ do_auth (app_t app, const char *keyidstr,
log_error ("key %s may not be used for authentication\n", keyidstr);
return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
}
- return do_sign (app, keyidstr, GCRY_MD_SHA1, pincb, pincb_arg,
+
+ algo = indatalen == 36? GCRY_MD_USER_TLS_MD5SHA1 : GCRY_MD_SHA1;
+ return do_sign (app, keyidstr, algo, pincb, pincb_arg,
indata, indatalen, outdata, outdatalen);
}
diff --git a/scd/scdaemon.h b/scd/scdaemon.h
index 40a398856..2d20b0231 100644
--- a/scd/scdaemon.h
+++ b/scd/scdaemon.h
@@ -34,7 +34,17 @@
#include "../common/errors.h"
-#define MAX_DIGEST_LEN 24
+/* To convey some special hash algorithms we use algorithm numbers
+ reserved for application use. */
+#ifndef GCRY_MD_USER
+#define GCRY_MD_USER 1024
+#endif
+#define GCRY_MD_USER_TLS_MD5SHA1 (GCRY_MD_USER+1)
+
+/* Maximum length of a digest. */
+#define MAX_DIGEST_LEN 36
+
+
/* A large struct name "opt" to keep global flags. */
struct