summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/hx509/crypto.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2008-03-19 10:17:42 +1100
committerAndrew Bartlett <abartlet@samba.org>2008-03-19 10:17:42 +1100
commit9e6b0c28712ee77ce878809c8576826a3ba08d95 (patch)
tree1a325e474fbc22b1a1cadaf53a3af2c36e8d5ad2 /source4/heimdal/lib/hx509/crypto.c
parent3530099cf226d591b687715b63b144d243e52083 (diff)
downloadsamba-9e6b0c28712ee77ce878809c8576826a3ba08d95.tar.gz
samba-9e6b0c28712ee77ce878809c8576826a3ba08d95.tar.bz2
samba-9e6b0c28712ee77ce878809c8576826a3ba08d95.zip
Merge lorikeet-heimdal -r 787 into Samba4 tree.
Andrew Bartlett (This used to be commit d88b530522d3cef67c24422bd5182fb875d87ee2)
Diffstat (limited to 'source4/heimdal/lib/hx509/crypto.c')
-rw-r--r--source4/heimdal/lib/hx509/crypto.c194
1 files changed, 131 insertions, 63 deletions
diff --git a/source4/heimdal/lib/hx509/crypto.c b/source4/heimdal/lib/hx509/crypto.c
index d86300bd58..e0f00ad7b4 100644
--- a/source4/heimdal/lib/hx509/crypto.c
+++ b/source4/heimdal/lib/hx509/crypto.c
@@ -32,7 +32,7 @@
*/
#include "hx_locl.h"
-RCSID("$Id: crypto.c 21318 2007-06-25 19:46:32Z lha $");
+RCSID("$Id: crypto.c 22435 2008-01-14 20:53:56Z lha $");
struct hx509_crypto;
@@ -64,6 +64,7 @@ struct hx509_private_key_ops {
int (*generate_private_key)(hx509_context,
struct hx509_generate_private_context *,
hx509_private_key);
+ BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *);
int (*handle_alg)(const hx509_private_key,
const AlgorithmIdentifier *,
enum crypto_op_type);
@@ -115,6 +116,9 @@ struct signature_alg {
#define SIG_PUBLIC_SIG 0x200
#define SIG_SECRET 0x400
+#define RA_RSA_USES_DIGEST_INFO 0x1000000
+
+
int (*verify_signature)(hx509_context context,
const struct signature_alg *,
const Certificate *,
@@ -248,43 +252,57 @@ rsa_verify_signature(hx509_context context,
}
if (retsize > tosize)
_hx509_abort("internal rsa decryption failure: ret > tosize");
- ret = decode_DigestInfo(to, retsize, &di, &size);
- free(to);
- if (ret) {
- goto out;
- }
- /* Check for extra data inside the sigature */
- if (size != retsize) {
- ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
- hx509_set_error_string(context, 0, ret, "size from decryption mismatch");
- goto out;
- }
+ if (sig_alg->flags & RA_RSA_USES_DIGEST_INFO) {
- if (sig_alg->digest_oid &&
- der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
- (*sig_alg->digest_oid)()) != 0)
- {
- ret = HX509_CRYPTO_OID_MISMATCH;
- hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
- goto out;
- }
+ ret = decode_DigestInfo(to, retsize, &di, &size);
+ free(to);
+ if (ret) {
+ goto out;
+ }
+
+ /* Check for extra data inside the sigature */
+ if (size != retsize) {
+ ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
+ hx509_set_error_string(context, 0, ret, "size from decryption mismatch");
+ goto out;
+ }
+
+ if (sig_alg->digest_oid &&
+ der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
+ (*sig_alg->digest_oid)()) != 0)
+ {
+ ret = HX509_CRYPTO_OID_MISMATCH;
+ hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
+ goto out;
+ }
+
+ /* verify that the parameters are NULL or the NULL-type */
+ if (di.digestAlgorithm.parameters != NULL &&
+ (di.digestAlgorithm.parameters->length != 2 ||
+ memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))
+ {
+ ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
+ hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");
+ goto out;
+ }
- /* verify that the parameters are NULL or the NULL-type */
- if (di.digestAlgorithm.parameters != NULL &&
- (di.digestAlgorithm.parameters->length != 2 ||
- memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))
- {
- ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
- hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");
- goto out;
+ ret = _hx509_verify_signature(context,
+ NULL,
+ &di.digestAlgorithm,
+ data,
+ &di.digest);
+ } else {
+ if (retsize != data->length ||
+ memcmp(to, data->data, retsize) != 0)
+ {
+ ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
+ hx509_set_error_string(context, 0, ret, "RSA Signature incorrect");
+ goto out;
+ }
+ free(to);
}
- ret = _hx509_verify_signature(context,
- NULL,
- &di.digestAlgorithm,
- data,
- &di.digest);
out:
free_DigestInfo(&di);
RSA_free(rsa);
@@ -303,7 +321,6 @@ rsa_create_signature(hx509_context context,
const AlgorithmIdentifier *digest_alg;
heim_octet_string indata;
const heim_oid *sig_oid;
- DigestInfo di;
size_t size;
int ret;
@@ -324,6 +341,8 @@ rsa_create_signature(hx509_context context,
digest_alg = hx509_signature_sha1();
} else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_rsaEncryption()) == 0) {
digest_alg = hx509_signature_sha1();
+ } else if (der_heim_oid_cmp(sig_oid, oid_id_heim_rsa_pkcs1_x509()) == 0) {
+ digest_alg = NULL;
} else
return HX509_ALG_NOT_SUPP;
@@ -335,29 +354,34 @@ rsa_create_signature(hx509_context context,
}
}
- memset(&di, 0, sizeof(di));
+ if (digest_alg) {
+ DigestInfo di;
+ memset(&di, 0, sizeof(di));
- ret = _hx509_create_signature(context,
- NULL,
- digest_alg,
- data,
- &di.digestAlgorithm,
- &di.digest);
- if (ret)
- return ret;
- ASN1_MALLOC_ENCODE(DigestInfo,
- indata.data,
- indata.length,
- &di,
- &size,
- ret);
- free_DigestInfo(&di);
- if (ret) {
- hx509_set_error_string(context, 0, ret, "out of memory");
- return ret;
+ ret = _hx509_create_signature(context,
+ NULL,
+ digest_alg,
+ data,
+ &di.digestAlgorithm,
+ &di.digest);
+ if (ret)
+ return ret;
+ ASN1_MALLOC_ENCODE(DigestInfo,
+ indata.data,
+ indata.length,
+ &di,
+ &size,
+ ret);
+ free_DigestInfo(&di);
+ if (ret) {
+ hx509_set_error_string(context, 0, ret, "out of memory");
+ return ret;
+ }
+ if (indata.length != size)
+ _hx509_abort("internal ASN.1 encoder error");
+ } else {
+ indata = *data;
}
- if (indata.length != size)
- _hx509_abort("internal ASN.1 encoder error");
sig->length = RSA_size(signer->private_key.rsa);
sig->data = malloc(sig->length);
@@ -371,7 +395,8 @@ rsa_create_signature(hx509_context context,
sig->data,
signer->private_key.rsa,
RSA_PKCS1_PADDING);
- der_free_octet_string(&indata);
+ if (indata.data != data->data)
+ der_free_octet_string(&indata);
if (ret <= 0) {
ret = HX509_CMS_FAILED_CREATE_SIGATURE;
hx509_set_error_string(context, 0, ret,
@@ -517,6 +542,18 @@ rsa_private_key_export(hx509_context context,
return 0;
}
+static BIGNUM *
+rsa_get_internal(hx509_context context, hx509_private_key key, const char *type)
+{
+ if (strcasecmp(type, "rsa-modulus") == 0) {
+ return BN_dup(key->private_key.rsa->n);
+ } else if (strcasecmp(type, "rsa-exponent") == 0) {
+ return BN_dup(key->private_key.rsa->e);
+ } else
+ return NULL;
+}
+
+
static hx509_private_key_ops rsa_private_key_ops = {
"RSA PRIVATE KEY",
@@ -524,7 +561,8 @@ static hx509_private_key_ops rsa_private_key_ops = {
rsa_private_key2SPKI,
rsa_private_key_export,
rsa_private_key_import,
- rsa_generate_private_key
+ rsa_generate_private_key,
+ rsa_get_internal
};
@@ -833,13 +871,24 @@ md2_verify_signature(hx509_context context,
return 0;
}
+static const struct signature_alg heim_rsa_pkcs1_x509 = {
+ "rsa-pkcs1-x509",
+ oid_id_heim_rsa_pkcs1_x509,
+ hx509_signature_rsa_pkcs1_x509,
+ oid_id_pkcs1_rsaEncryption,
+ NULL,
+ PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ rsa_verify_signature,
+ rsa_create_signature
+};
+
static const struct signature_alg pkcs1_rsa_sha1_alg = {
"rsa",
oid_id_pkcs1_rsaEncryption,
hx509_signature_rsa_with_sha1,
oid_id_pkcs1_rsaEncryption,
NULL,
- PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
rsa_verify_signature,
rsa_create_signature
};
@@ -850,7 +899,7 @@ static const struct signature_alg rsa_with_sha256_alg = {
hx509_signature_rsa_with_sha256,
oid_id_pkcs1_rsaEncryption,
oid_id_sha256,
- PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
rsa_verify_signature,
rsa_create_signature
};
@@ -861,7 +910,7 @@ static const struct signature_alg rsa_with_sha1_alg = {
hx509_signature_rsa_with_sha1,
oid_id_pkcs1_rsaEncryption,
oid_id_secsig_sha_1,
- PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
rsa_verify_signature,
rsa_create_signature
};
@@ -872,7 +921,7 @@ static const struct signature_alg rsa_with_md5_alg = {
hx509_signature_rsa_with_md5,
oid_id_pkcs1_rsaEncryption,
oid_id_rsa_digest_md5,
- PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
rsa_verify_signature,
rsa_create_signature
};
@@ -883,7 +932,7 @@ static const struct signature_alg rsa_with_md2_alg = {
hx509_signature_rsa_with_md2,
oid_id_pkcs1_rsaEncryption,
oid_id_rsa_digest_md2,
- PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
rsa_verify_signature,
rsa_create_signature
};
@@ -952,7 +1001,7 @@ static const struct signature_alg *sig_algs[] = {
&pkcs1_rsa_sha1_alg,
&rsa_with_md5_alg,
&rsa_with_md2_alg,
- &pkcs1_rsa_sha1_alg,
+ &heim_rsa_pkcs1_x509,
&dsa_sha1_alg,
&sha256_alg,
&sha1_alg,
@@ -1423,6 +1472,11 @@ const AlgorithmIdentifier _hx509_signature_rsa_data = {
{ 7, rk_UNCONST(rsa_oid) }, NULL
};
+static const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 };
+const AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = {
+ { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL
+};
+
static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 };
const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = {
{ 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL
@@ -1491,6 +1545,10 @@ hx509_signature_rsa(void)
{ return &_hx509_signature_rsa_data; }
const AlgorithmIdentifier *
+hx509_signature_rsa_pkcs1_x509(void)
+{ return &_hx509_signature_rsa_pkcs1_x509_data; }
+
+const AlgorithmIdentifier *
hx509_crypto_des_rsdi_ede3_cbc(void)
{ return &_hx509_des_rsdi_ede3_cbc_oid; }
@@ -1597,6 +1655,16 @@ _hx509_private_key_exportable(hx509_private_key key)
return 1;
}
+BIGNUM *
+_hx509_private_key_get_internal(hx509_context context,
+ hx509_private_key key,
+ const char *type)
+{
+ if (key->ops->get_internal == NULL)
+ return NULL;
+ return (*key->ops->get_internal)(context, key, type);
+}
+
int
_hx509_private_key_export(hx509_context context,
const hx509_private_key key,