/** * rsa_get_pub_key() - read a public key from a .crt file * * @keydir: Directory containins the key * @name Name of key file (will have a .crt extension) * @rsap Returns RSA object, or NULL on failure * @return 0 if ok, -ve on error (in which case *rsap will be set to NULL) */ static int rsa_get_pub_key(const char *keydir, const char *name, RSA **rsap) { char path[1024]; EVP_PKEY *key; X509 *cert; RSA *rsa; FILE *f; int ret; *rsap = NULL; snprintf(path, sizeof(path), "%s/%s.crt", keydir, name); f = fopen(path, "r"); if (!f) { fprintf(stderr, "Couldn't open RSA certificate: '%s': %s\n", path, strerror(errno)); return -EACCES; } /* Read the certificate */ cert = NULL; if (!PEM_read_X509(f, &cert, NULL, NULL)) { rsa_err("Couldn't read certificate"); ret = -EINVAL; goto err_cert; } /* Get the public key from the certificate. */ key = X509_get_pubkey(cert); if (!key) { rsa_err("Couldn't read public key\n"); ret = -EINVAL; goto err_pubkey; } /* Convert to a RSA_style key. */ rsa = EVP_PKEY_get1_RSA(key); if (!rsa) { rsa_err("Couldn't convert to a RSA style key"); ret = -EINVAL; goto err_rsa; } fclose(f); EVP_PKEY_free(key); X509_free(cert); *rsap = rsa; return 0; err_rsa: EVP_PKEY_free(key); err_pubkey: X509_free(cert); err_cert: fclose(f); return ret; }
/** * rsa_get_priv_key() - read a private key from a .key file * * @keydir: Directory containins the key * @name Name of key file (will have a .key extension) * @rsap Returns RSA object, or NULL on failure * @return 0 if ok, -ve on error (in which case *rsap will be set to NULL) */ static int rsa_get_priv_key(const char *keydir, const char *name, RSA **rsap) { char path[1024]; RSA *rsa; FILE *f; *rsap = NULL; snprintf(path, sizeof(path), "%s/%s.key", keydir, name); f = fopen(path, "r"); if (!f) { fprintf(stderr, "Couldn't open RSA private key: '%s': %s\n", path, strerror(errno)); return -ENOENT; } rsa = PEM_read_RSAPrivateKey(f, 0, NULL, path); if (!rsa) { rsa_err("Failure reading private key"); fclose(f); return -EPROTO; } fclose(f); *rsap = rsa; return 0; }
static int rsa_get_priv_key(const char *key_path, RSA **rsap) { RSA *rsa; FILE *f; *rsap = NULL; f = fopen(key_path, "r"); if (!f) { fprintf(stderr, "Couldn't open RSA private key: '%s': %s\n", key_path, strerror(errno)); return -ENOENT; } rsa = PEM_read_RSAPrivateKey(f, 0, NULL, (void *)key_path); if (!rsa) { rsa_err("Failure reading private key"); fclose(f); return -EPROTO; } fclose(f); *rsap = rsa; return 0; }
static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo, const struct image_region region[], int region_count, uint8_t **sigp, uint *sig_size) { EVP_PKEY *key; EVP_MD_CTX *context; int size, ret = 0; uint8_t *sig; int i; key = EVP_PKEY_new(); if (!key) return rsa_err("EVP_PKEY object creation failed"); if (!EVP_PKEY_set1_RSA(key, rsa)) { ret = rsa_err("EVP key setup failed"); goto err_set; } size = EVP_PKEY_size(key); sig = malloc(size); if (!sig) { fprintf(stderr, "Out of memory for signature (%d bytes)\n", size); ret = -ENOMEM; goto err_alloc; } context = EVP_MD_CTX_create(); if (!context) { ret = rsa_err("EVP context creation failed"); goto err_create; } EVP_MD_CTX_init(context); if (!EVP_SignInit(context, checksum_algo->calculate_sign())) { ret = rsa_err("Signer setup failed"); goto err_sign; } for (i = 0; i < region_count; i++) { if (!EVP_SignUpdate(context, region[i].data, region[i].size)) { ret = rsa_err("Signing data failed"); goto err_sign; } } if (!EVP_SignFinal(context, sig, sig_size, key)) { ret = rsa_err("Could not obtain signature"); goto err_sign; } EVP_MD_CTX_cleanup(context); EVP_MD_CTX_destroy(context); EVP_PKEY_free(key); debug("Got signature: %d bytes, expected %d\n", *sig_size, size); *sigp = sig; *sig_size = size; return 0; err_sign: EVP_MD_CTX_destroy(context); err_create: free(sig); err_alloc: err_set: EVP_PKEY_free(key); return ret; }
static int rsa_sign_with_key(RSA *rsa, const void *data, const int data_size, uint8_t **sigp, uint *sig_size) { EVP_PKEY *key; EVP_MD_CTX *context; int size, ret = 0; uint8_t *sig; key = EVP_PKEY_new(); if (!key) return rsa_err("EVP_PKEY object creation failed"); if (!EVP_PKEY_set1_RSA(key, rsa)) { ret = rsa_err("EVP key setup failed"); goto err_set; } size = EVP_PKEY_size(key); sig = malloc(size); if (!sig) { fprintf(stderr, "Out of memory for signature (%d bytes)\n", size); ret = -ENOMEM; goto err_alloc; } context = EVP_MD_CTX_create(); if (!context) { ret = rsa_err("EVP context creation failed"); goto err_create; } EVP_MD_CTX_init(context); if (!EVP_SignInit(context, EVP_sha1())) { ret = rsa_err("Signer setup failed"); goto err_sign; } if (!EVP_SignUpdate(context, data, data_size)) { ret = rsa_err("Signing data failed"); goto err_sign; } if (!EVP_SignFinal(context, sig, sig_size, key)) { ret = rsa_err("Could not obtain signature"); goto err_sign; } EVP_MD_CTX_cleanup(context); EVP_MD_CTX_destroy(context); EVP_PKEY_free(key); printf("Got signature: %d bytes, expected %d\n", *sig_size, size); *sigp = sig; *sig_size = size; return 0; err_sign: EVP_MD_CTX_destroy(context); err_create: free(sig); err_alloc: err_set: EVP_PKEY_free(key); return ret; }