summaryrefslogtreecommitdiff
path: root/lib/x509/mpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/x509/mpi.c')
-rw-r--r--lib/x509/mpi.c122
1 files changed, 109 insertions, 13 deletions
diff --git a/lib/x509/mpi.c b/lib/x509/mpi.c
index 2bb3e54aaa..bd47d3244c 100644
--- a/lib/x509/mpi.c
+++ b/lib/x509/mpi.c
@@ -134,7 +134,7 @@ _gnutls_get_asn_mpis(ASN1_TYPE asn, const char *root,
* then the issuer's parameters should be used. This is not
* done yet.
*/
- if (pk_algorithm != GNUTLS_PK_RSA) { /* RSA doesn't use parameters */
+ if (pk_algorithm != GNUTLS_PK_RSA) { /* RSA doesn't use parameters */
result = _gnutls_x509_read_value(asn, name, &tmp);
if (result < 0) {
gnutls_assert();
@@ -169,6 +169,12 @@ _gnutls_get_asn_mpis(ASN1_TYPE asn, const char *root,
goto error;
}
+ result = _gnutls_x509_check_pubkey_params(pk_algorithm, params);
+ if (result < 0) {
+ gnutls_assert();
+ goto error;
+ }
+
result = 0;
error:
@@ -205,16 +211,89 @@ _gnutls_x509_crq_get_mpis(gnutls_x509_crq_t cert,
}
/*
- * This function writes and encodes the parameters for DSS or RSA keys.
+ * This function reads and decodes the parameters for DSS or RSA keys.
* This is the "signatureAlgorithm" fields.
- *
- * If @legacy is non-zero then the legacy value for PKCS#7 signatures
- * will be written for RSA signatures.
*/
int
-_gnutls_x509_write_sig_params(ASN1_TYPE dst, const char *dst_name,
- gnutls_pk_algorithm_t pk_algorithm,
- gnutls_digest_algorithm_t dig, unsigned legacy)
+_gnutls_x509_read_sign_params(ASN1_TYPE src, const char *src_name,
+ gnutls_x509_spki_st *params)
+{
+ int result;
+ char name[128];
+ char oid[MAX_OID_SIZE];
+ int oid_size;
+
+ _gnutls_str_cpy(name, sizeof(name), src_name);
+ _gnutls_str_cat(name, sizeof(name), ".algorithm");
+
+ oid_size = sizeof(oid);
+ result = asn1_read_value(src, name, oid, &oid_size);
+
+ if (result != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(result);
+ }
+
+ if (strcmp (oid, PK_PKIX1_RSA_PSS_OID) == 0) {
+ gnutls_datum_t tmp = { NULL, 0 };
+
+ _gnutls_str_cpy(name, sizeof(name), src_name);
+ _gnutls_str_cat(name, sizeof(name), ".parameters");
+
+ result = _gnutls_x509_read_value(src, name, &tmp);
+ if (result < 0 &&
+ result != GNUTLS_E_ASN1_ELEMENT_NOT_FOUND &&
+ result != GNUTLS_E_ASN1_VALUE_NOT_FOUND) {
+ _gnutls_free_datum(&tmp);
+ return gnutls_assert_val(result);
+ }
+
+ result = _gnutls_x509_read_rsa_pss_params(tmp.data, tmp.size,
+ params);
+ _gnutls_free_datum(&tmp);
+
+ if (result < 0)
+ gnutls_assert();
+
+ return result;
+ } else {
+ memset(params, 0, sizeof(gnutls_x509_spki_st));
+
+ result = gnutls_oid_to_sign(oid);
+ if (result != GNUTLS_SIGN_UNKNOWN) {
+ params->pk = gnutls_sign_get_pk_algorithm(result);
+ params->dig = gnutls_sign_get_hash_algorithm(result);
+ }
+ }
+
+ return 0;
+}
+
+int
+_gnutls_x509_crt_read_sign_params(gnutls_x509_crt_t crt,
+ gnutls_x509_spki_st *params)
+{
+ return _gnutls_x509_read_sign_params(crt->cert,
+ "tbsCertificate."
+ "subjectPublicKeyInfo."
+ "algorithm",
+ params);
+}
+
+int
+_gnutls_x509_crq_read_sign_params(gnutls_x509_crq_t crt,
+ gnutls_x509_spki_st *params)
+{
+ return _gnutls_x509_read_sign_params(crt->crq,
+ "certificationRequestInfo."
+ "subjectPKInfo."
+ "algorithm",
+ params);
+}
+
+int
+_gnutls_x509_write_sign_params(ASN1_TYPE dst, const char *dst_name,
+ gnutls_x509_spki_st *params)
{
int result;
char name[128];
@@ -223,15 +302,18 @@ _gnutls_x509_write_sig_params(ASN1_TYPE dst, const char *dst_name,
_gnutls_str_cpy(name, sizeof(name), dst_name);
_gnutls_str_cat(name, sizeof(name), ".algorithm");
- if (legacy && pk_algorithm == GNUTLS_PK_RSA)
+ if (params->legacy && params->pk == GNUTLS_PK_RSA)
oid = PK_PKIX1_RSA_OID;
+ else if (params->pk == GNUTLS_PK_RSA_PSS)
+ oid = PK_PKIX1_RSA_PSS_OID;
else
- oid = gnutls_sign_get_oid(gnutls_pk_to_sign(pk_algorithm, dig));
+ oid = gnutls_sign_get_oid(gnutls_pk_to_sign(params->pk,
+ params->dig));
if (oid == NULL) {
gnutls_assert();
_gnutls_debug_log
("Cannot find OID for sign algorithm pk: %d dig: %d\n",
- (int) pk_algorithm, (int) dig);
+ (int) params->pk, (int) params->dig);
return GNUTLS_E_INVALID_REQUEST;
}
@@ -247,10 +329,24 @@ _gnutls_x509_write_sig_params(ASN1_TYPE dst, const char *dst_name,
_gnutls_str_cpy(name, sizeof(name), dst_name);
_gnutls_str_cat(name, sizeof(name), ".parameters");
- if (pk_algorithm == GNUTLS_PK_RSA)
+ if (params->pk == GNUTLS_PK_RSA)
result =
asn1_write_value(dst, name, ASN1_NULL, ASN1_NULL_SIZE);
- else
+ else if (params->pk == GNUTLS_PK_RSA_PSS) {
+ gnutls_datum_t tmp = { NULL, 0 };
+
+ if (params == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ result = _gnutls_x509_write_rsa_pss_params(params, &tmp);
+ if (result < 0)
+ return gnutls_assert_val(result);
+
+ result = asn1_write_value(dst, name, tmp.data, tmp.size);
+ _gnutls_free_datum(&tmp);
+ } else
result = asn1_write_value(dst, name, NULL, 0);
if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND) {