identification_t **keyid_info);
/**
- * Verification of an EMPSA PKCS1 signature described in PKCS#1
+ * verification of a padded PKCS1 signature without an OID
+ */
+static bool verify_raw(private_gcrypt_rsa_public_key_t *this,
+ chunk_t data, chunk_t signature)
+{
+ gcry_sexp_t in, sig;
+ gcry_error_t err;
+ chunk_t em;
+ size_t k;
+
+ /* EM = 0x00 || 0x01 || PS || 0x00 || T
+ * PS = 0xFF padding, with length to fill em
+ * T = data
+ */
+ k = gcry_pk_get_nbits(this->key) / 8;
+ if (data.len > k - 3)
+ {
+ return FALSE;
+ }
+ em = chunk_alloc(k);
+ memset(em.ptr, 0xFF, em.len);
+ em.ptr[0] = 0x00;
+ em.ptr[1] = 0x01;
+ em.ptr[em.len - data.len - 1] = 0x00;
+ memcpy(em.ptr + em.len - data.len, data.ptr, data.len);
+
+ err = gcry_sexp_build(&in, NULL, "(data(flags raw)(value %b))",
+ em.len, em.ptr);
+ chunk_free(&em);
+ if (err)
+ {
+ DBG1("building data S-expression failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ err = gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))",
+ signature.len, signature.ptr);
+ if (err)
+ {
+ DBG1("building signature S-expression failed: %s", gpg_strerror(err));
+ gcry_sexp_release(in);
+ return FALSE;
+ }
+ err = gcry_pk_verify(sig, in, this->key);
+ gcry_sexp_release(in);
+ gcry_sexp_release(sig);
+ if (err)
+ {
+ DBG1("RSA signature verification failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Verification of an EMSA PKCS1 signature described in PKCS#1
*/
static bool verify_pkcs1(private_gcrypt_rsa_public_key_t *this,
hash_algorithm_t algorithm, char *hash_name,
{
switch (scheme)
{
+ case SIGN_RSA_EMSA_PKCS1_NULL:
+ return verify_raw(this, data, signature);
case SIGN_RSA_EMSA_PKCS1_MD5:
return verify_pkcs1(this, HASH_MD5, "md5", data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA1:
}
/**
- * Implementation of public_key_t.get_keysize.
+ * Implementation of public_key_t.encrypt.
*/
-static bool encrypt_(private_gcrypt_rsa_public_key_t *this, chunk_t crypto,
- chunk_t *plain)
+static bool encrypt_(private_gcrypt_rsa_public_key_t *this, chunk_t plain,
+ chunk_t *encrypted)
{
- DBG1("RSA public key encryption not implemented");
- return FALSE;
+ gcry_sexp_t in, out;
+ gcry_error_t err;
+
+ /* "pkcs1" uses PKCS 1.5 (section 8.1) block type 2 encryption:
+ * 00 | 02 | RANDOM | 00 | DATA */
+ err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(value %b))",
+ plain.len, plain.ptr);
+ if (err)
+ {
+ DBG1("building encryption S-expression failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ err = gcry_pk_encrypt(&out, in, this->key);
+ gcry_sexp_release(in);
+ if (err)
+ {
+ DBG1("encrypting data using pkcs1 failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ *encrypted = gcrypt_rsa_find_token(out, "a");
+ gcry_sexp_release(out);
+ return !!encrypted->len;
}
/**