/yan_key

an easy used lib for keystore

Primary LanguageCApache License 2.0Apache-2.0

YAN-KEY (under developing)

Note: I'm not a native speaker, if the following instruction is unclear, please feel relaxed to contact the auther 'stxr.long@gmail.com'

Overview

This is an easy used key operator library depends on the OpenSSL. Usually, it requires a relatively learning cost to use the OpenSSL. I put a shell on the basis of OpenSSL so that you only need to understand the key usage through common sense. You just need to create a key_context with a specified key type and call the decrypt/encrypt or sign/verify functions, you do not need to understand what's in key_context, and you don't even need to know what EVP_PKEY and EVP_PKEY_CTX are, especially for those deeper operations provided by OpenSSL.

Feature

We support the following keys:

  • AES with encryption
  • RSA with encryption and signature
  • ECC with signature (if you have read the source code, you can add the elliptic curves rapidly)

and we also support the operations with certificate.

This project is under developing, more keys will be added soon, or you can provide the pull request after you read the source code, it is very easy to extend the key usage.

Build

You can just copy the following files to your own project, and build with depending library -lcrypto, or you can build as follows:

mkdir build
cd build
cmake ..

Usage

key

It's easy to use this library, you can refer to the test cases under the directory test/, here we provide an example:

/* create a key context pointer, you need not to know what's in it */
struct key_context *ctx = NULL;
/* 
 * init the key context with key type
 * of course, you can import the existed key instead of creating a new one
 * 
 * please check the return value, 0 is ok, otherwise, failed
 */
int ret = create_key_context(&ctx, KEY_RSA_2048 /* choose what type you want to operate */);

/* now you can do encryption/decryption or sign/verify */
ret = encrypt_with_key(ctx, (uint8_t *)plaintext, (int)strlen(plaintext), out, &olen);
ret = decrypt_with_key(ctx, (uint8_t *)plaintext, (int)strlen(plaintext), out, &olen);

ret = sign_with_key(ctx, (uint8_t *)plaintext, (int)strlen(plaintext), out, &olen);
ret = verify_with_key(ctx, (uint8_t *)plaintext, (int)strlen(plaintext), out, olen);

/* or you can export/import the key for storage */
ret = export_pubkey(ctx, out, olen);
/*
 * you also need to call the export_prikey for symmetric key
 * passwd is another symmetric key context you created before
 */
ret = export_prikey(ctx, out, olen, passwd);

/*
 * we don't know what type of the key you imported, so you must specify the key type
 */
ret = import_pubkey(&ctx, type, in, ilen);
ret = import_prikey(&ctx, type, in, ilen, passwd);

certificate

Certificate operations are like the pure key, we also provide the funtions, such as createencryptionsignature. But there are some differences, the certificate has chain operations and each certificate has its own speical contents. We have implemented key operations for certificates like cert_reqeust, issue a sub cert with a CA cert, and you can set subject for each determined certificate. We will soon release the function for you to self-define the V3 extension, which is hard to understand for first-time certificate users. the example is as follows (test cases are under directory test/):

// create a certificate request with determined key type, certificate only supports the asymmetric key
const char *errmsg = NULL;
struct cert_subject subj = {0};
memcpy(subj.organization, "yan", sizeof("yan"));
memcpy(subj.organization_unit, "R&D", sizeof("R&D"));
memcpy(subj.country_name, "CN", sizeof("CN"));
memcpy(subj.province_name, "taiwan", sizeof("taiwan"));
memcpy(subj.locality_name, "taipei", sizeof("taipei"));
memcpy(subj.common_name, "root CA", sizeof("root CA"));

struct cert_req_context *ca_req = NULL;
int ret = create_cert_req(&ca_req, KEY_RSA_2048, &subj);
if(ret < 0) {
	errmsg = get_err_msg(ret);
	/* error operations */
}

// self-issued CA certificate with valid date
struct cert_context *ca_cert = NULL;
ret = issue_ca_cert(&ca_cert, ca_req, 365);
if(ret < 0) /* error operations */

/*
 * of course, you can issue the sub cert
 * you can set a non-zero value for argument 'issueca' to issue a subca cert
 */
ret = issue_sub_cert(&cert, ca_cert, req, 1, 365);
if(ret < 0) /* error operations */

// just use it like pure key context with encryption or signing

No complicated logics, just use the library base on your common sense, if not, please let me know and then optimize it out. I'm confident that you can understand the use of all the interfaces, so I won't make too many intepretation on them.