generate RSA keypair with openssl - c

I'm trying to generate set of RSA keys using EVP_RSA_gen interface from openssl/evp.h.
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/err.h>
int main() {
EVP_PKEY *pkey = NULL;
pkey = EVP_RSA_gen(4096);
if (pkey == NULL){
ERR_print_errors_fp(stderr);
printf("Key generation failed.\n");
}
size_t keyLen;
if (EVP_PKEY_get_raw_public_key(pkey, NULL, &keyLen) != 1) {
ERR_print_errors_fp(stderr);
printf("Key extraction failed.\n");
}
return 0;
}
However, when I try to get the size of a raw public key using EVP_PKEY_get_raw_public_key as described here, it fails and the Key extraction failed gets printed. ERR_print_errors_fp doesn't output any message.
What am I doing wrong? It seems there are no mistakes in the code.

Related

Revoke existing certificate in openssl

I have created openssl certificates so i have .crt and .key file. If I want to add those certificates in existing certificate revocation list then how can we do that ?
I have tried with below code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <openssl/pem.h>
#include <openssl/conf.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
#define DB_NUMBER 6
#define DB_name 5
#define DB_serial 3
#define DB_rev_date 2
static X509* load_cert(const char* usercert)
{
/* read usercert from file */
X509* x = NULL;
BIO* bio = BIO_new(BIO_s_file());
assert(bio != NULL);
assert(BIO_read_filename(bio, usercert) > 0);
x = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
BIO_free(bio);
assert(x != NULL);
return x;
}
int main()
{
int i;
ASN1_UTCTIME* tm = NULL;
char* rev_str = NULL;
BIGNUM* bn = NULL;
char* row[DB_NUMBER];
for (i = 0; i < DB_NUMBER; i++)
row[i] = NULL;
X509* x = load_cert("../client.crt");
row[DB_name] = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0);
bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x), NULL);
assert(bn != NULL);
if (BN_is_zero(bn))
row[DB_serial] = BUF_strdup("00");
else
row[DB_serial] = BN_bn2hex(bn);
BN_free(bn);
//assert(row[DB_name] != NULL);
//assert(row[DB_serial] != NULL);
printf("Serial Number is: %s\n", row[DB_serial]);
printf("---- Now Updating CRL file with expired client certificates --------\n");
char *crl_file_path = "../root_mod.crl";
FILE *fp_crl_file = NULL;
X509_CRL *x_crl = NULL;
BIGNUM* serial = NULL;
/* Get the CA crl */
fp_crl_file = fopen(crl_file_path, "r");
if (!fp_crl_file)
{
printf("---- Error while opening CRL file --------\n");
exit(1);
}
x_crl = PEM_read_X509_CRL(fp_crl_file, NULL, NULL, NULL);
if (!x_crl)
{
printf("---- Error while reading X509 CRL file --------\n");
exit(1);
}
fclose(fp_crl_file);
X509_REVOKED* r = X509_REVOKED_new();
assert(r != NULL);
assert(BN_hex2bn(&serial, row[DB_serial]) > 0);
ASN1_INTEGER* tmpser = BN_to_ASN1_INTEGER(serial, NULL);
BN_free(serial);
serial = NULL;
assert(tmpser != NULL);
i = X509_REVOKED_set_serialNumber(r, tmpser);
ASN1_INTEGER_free(tmpser);
X509_CRL_add0_revoked(x_crl, r);
return 0;
}
I have wrote above code and i got the serial number but do not get added to revoked list in "root_mod.crl" file.
Can you suggest any pointers ?

Load public key to create rsa object for public encryption

I am trying to load a rsa object from a generated public key. I used PEM_write_bio_RSAPublicKey to generate the public key string. Then I used PEM_read_bio_RSA_PUBKEY to load the rsa object from the public key string. The problem is the rsa object is null. The generated string looks okay as far as I can tell. Any ideas?
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAxIReUspesPy6a4CPBjt/4Jt+H13q9MekMiutzNKdNO1uuwqcdqDX
pKPeTKXyUH6oCyRdUxkk6IVXGlBlxtW7OsxaYWhpfl9z3CCERCEpFmzN++dvlK2v
mckFL66e9q6Y+HwgyP1LJqrszeqlg2d29TCVKfD/UURVNmc/nPPjs9nO+IDhh7+P
NTQ2OqGBq8ghwVL5ZZyW3yVO5OAbRB6pjKBe9+j4B2TGnD5JO9Nu0jlFANZOKFJu
HDVE3XuTvOkuzL2i8Lwp4Myk42tbIgcCe4G58vKFddL651rWhg4hN3fRSx5YtDnQ
r5cgfNBOAww58S8lwXgU8lvzvEoNV+WMgwIDAQAB
-----END RSA PUBLIC KEY-----
gcc test_public_private_key.c -lcrypto -o test
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
char* get_public_key() {
RSA* rsa = RSA_new();
int kbits = 2048;
BIGNUM* bne = BN_new();
BN_set_word(bne, RSA_F4);
int status = RSA_generate_key_ex(rsa, kbits, bne, NULL);
if(status == 0) {
fprintf(stderr, "rsa key generation failed\n");
}
BIO *bio = BIO_new(BIO_s_mem());
PEM_write_bio_RSAPublicKey(bio, rsa);
int length = BIO_pending(bio);
char* pem_key = malloc(length+1);
memset(pem_key, '\0', length+1);
BIO_read(bio, pem_key, length);
return pem_key;
}
int main(int argc, char* argv[]) {
char* public_key = get_public_key();
printf("%s", public_key);
BIO* keybio = BIO_new_mem_buf(public_key, -1);
if (keybio == NULL) {
fprintf(stderr, "failed to create key BIO");
}
printf("keybio: %p\n", keybio);
RSA* rsa = PEM_read_bio_RSA_PUBKEY(keybio, NULL, NULL, NULL);
printf("rsa result %p\n", rsa);
BIO_free(keybio);
free(public_key);
return 0;
}
I thought it would be good to add that the reason this didn't work is because PEM_read_RSA_PUBKEY expects a SubjectPublicKeyInfo structure, which starts with BEGIN PUBLIC KEY, while PEM_read_RSAPublicKey expects a RSAPublicKey structure, which starts with BEGIN RSA PUBLIC KEY.
PEM_write_bio_RSAPublicKey generated the latter which corresponds to the second function, PEM_read_RSAPublicKey.

RSA_verify() causes segmentation fault

Teh function below causes a segmentation fault when it gets to the RSA_verify() part. I'm a c-beginner so it's hard for me to find the reason for the problem. Maybe someone can point out what I'm doing wrong. It would be very helpful, thanks in advance.
Here's the Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
#include <openssl/dsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#define BUF 20000
#define DSS 20
int matchCipherToSign(unsigned char *signPath, char *cipherPath) {
unsigned char *bufCipher = malloc(BUF);
unsigned char *sha = malloc(SHA_DIGEST_LENGTH);
unsigned char *bufSign = malloc(BUF);
unsigned int retSign;
int ret=0;
int retCipher;
FILE *key;
RSA *rsa = RSA_new();
EVP_MD_CTX ctx;
key = fopen("key.bin", "rb");
if (key == NULL){
printf("Couldn't open file key.bin.\n");
exit(EXIT_FAILURE);
}
retSign = readFile(signPath, bufSign);
if (retSign == 0){
printf("Couldn't read file %s.\n", signPath);
exit(EXIT_FAILURE);
}
retCipher = readFile(cipherPath, bufCipher);
if (retCipher == 0){
printf("Couldn't open file %s.\n", cipherPath);
exit(EXIT_FAILURE);
}
rsa = PEM_read_RSA_PUBKEY(key, &rsa, NULL, NULL);
fclose(key);
if (1!=EVP_DigestInit(&ctx, EVP_sha1())) {
printf("EVP_DigestInit Error.\n");
exit(EXIT_FAILURE);
}
if (1!=EVP_DigestUpdate(&ctx, bufCipher, retCipher)) {
printf("VP_DigestUpdate Error.\n");
exit(EXIT_FAILURE);
}
if (1!=EVP_DigestFinal(&ctx, sha, NULL)) {
printf("EVP_DigestFinal Error.\n");
exit(EXIT_FAILURE);
}
ret = RSA_verify(NID_sha1, sha, SHA_DIGEST_LENGTH, bufSign, sizeof(bufSign), rsa);
RSA_free(rsa);
free(bufCipher);
free(bufSign);
free(sha);
return ret;
}
Thanks for your help!

How to do double authentication using libssh module?

My SSH server uses double authtication. I do not know how its implemented. But initially its asks for a password, then again asks for another password to login to a separate console which is different from usual control.
My code is similar to the example code shown in the documentations,
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <libssh/libssh.h>
int main(int argc, char * argv[])
{
ssh_session my_ssh_session = ssh_new();
int rc;
char * password;
char * username = "admin";
// Check if ssh session exists.
if(my_ssh_session == NULL)
{
exit(-1);
}
ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "x.x.x.x");
rc = ssh_connect(my_ssh_session);
if (rc != SSH_OK)
{
fprintf(stderr, "Error Connecting to Server: %s.\n", ssh_get_error(my_ssh_session));
exit(-1);
}
password = getpass("Password: ");
rc = ssh_userauth_password(my_ssh_session, username, password);
if (rc != SSH_AUTH_SUCCESS)
{
fprintf(stderr, "ERROR Authenticating: %s.\n", ssh_get_error(my_ssh_session));
ssh_disconnect(my_ssh_session);
ssh_free(my_ssh_session);
}
else
{
printf("Authentication Successful.\n");
}
ssh_free(my_ssh_session);
}
How do i implement a double authtication in this ? can you kindly help me out ?
What version of
libssh do you have?
"versions 0.5.1 and above have a logical error in the handling of a SSH_MSG_NEWKEYS and SSH_MSG_KEXDH_REPLY package. A detected error did not set the session into the error state correctly and further processed the packet which leads to a null pointer dereference. This is the packet after the initial key exchange and doesn’t require authentication."
Ref libssh

openssl: how to read a .crt file..?

I want to read the certifi.crt file using OpenSSL API (not in commands). I have no idea how to do that. If any one knows, please help me. Thank you.
If you give example code that will be very helpful.
If the ".crt" extension refers to a PEM text file (begins with -----BEGIN CERTIFICATE----- followed by base64), then get started in the OpenSSL docs here.
Here is some code to get you started (link with ssl, e.g. g++ a.c -lssl):
#include <stdio.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
int main(int argc, char** argv)
{
FILE* f = fopen("certifi.crt", "r");
if (f != NULL)
{
X509* x509 = PEM_read_X509(f, NULL, NULL, NULL);
if (x509 != NULL)
{
char* p = X509_NAME_oneline(X509_get_issuer_name(x509), 0, 0);
if (p)
{
printf("NAME: %s\n", p);
OPENSSL_free(p);
}
X509_free(x509);
}
}
return 0;
}

Resources