aboutsummaryrefslogtreecommitdiffstats
path: root/libparc/parc/security/parc_X509Certificate.c
diff options
context:
space:
mode:
Diffstat (limited to 'libparc/parc/security/parc_X509Certificate.c')
-rw-r--r--libparc/parc/security/parc_X509Certificate.c253
1 files changed, 191 insertions, 62 deletions
diff --git a/libparc/parc/security/parc_X509Certificate.c b/libparc/parc/security/parc_X509Certificate.c
index 8cc4b0b7..67ee6b2b 100644
--- a/libparc/parc/security/parc_X509Certificate.c
+++ b/libparc/parc/security/parc_X509Certificate.c
@@ -29,6 +29,7 @@
#include <parc/algol/parc_Buffer.h>
#include <parc/algol/parc_Object.h>
#include <parc/algol/parc_Memory.h>
+#include <parc/security/parc_KeyType.h>
#include <openssl/bio.h>
#include <openssl/err.h>
@@ -398,91 +399,219 @@ parcX509Certificate_CreateFromDERBuffer(const PARCBuffer *buffer)
return cert;
}
-PARCX509Certificate *
-parcX509Certificate_CreateSelfSignedCertificate(PARCBuffer **privateKeyBuffer, char *subjectName, int keyLength, size_t validityDays)
+PARCX509Certificate * _createSelfSignedCertificate_RSA(PARCBuffer **privateKeyBuffer, char *subjectName, int keyLength, size_t validityDays)
{
- parcSecurity_AssertIsInitialized();
+ parcSecurity_AssertIsInitialized();
- RSA *rsa = RSA_new();
- assertNotNull(rsa, "RSA_new failed.");
+ RSA *rsa = RSA_new();
+ assertNotNull(rsa, "RSA_new failed.");
- EVP_PKEY *privateKey = EVP_PKEY_new();
- assertNotNull(privateKey, "EVP_PKEY_new() failed.");
+ EVP_PKEY *privateKey = EVP_PKEY_new();
+ assertNotNull(privateKey, "EVP_PKEY_new() failed.");
- X509 *cert = X509_new();
- assertNotNull(cert, "X509_new() failed.");
+ X509 *cert = X509_new();
+ assertNotNull(cert, "X509_new() failed.");
- int res;
- BIGNUM *pub_exp;
+ int res;
+ BIGNUM *pub_exp;
- pub_exp = BN_new();
+ pub_exp = BN_new();
- BN_set_word(pub_exp, RSA_F4);
- res = 1;
- bool result = false;
- if (RSA_generate_key_ex(rsa, keyLength, pub_exp, NULL)) {
- if (EVP_PKEY_set1_RSA(privateKey, rsa)) {
- if (X509_set_version(cert, 2)) { // 2 => X509v3
- result = true;
- }
- }
+ BN_set_word(pub_exp, RSA_F4);
+ res = 1;
+ bool result = false;
+ if (RSA_generate_key_ex(rsa, keyLength, pub_exp, NULL)) {
+ if (EVP_PKEY_set1_RSA(privateKey, rsa)) {
+ if (X509_set_version(cert, 2)) { // 2 => X509v3
+ result = true;
+ }
}
- if (result) {
- // add serial number
- if (_addRandomSerial(cert) == true) {
- if (_addValidityPeriod(cert, validityDays) == true) {
- if (X509_set_pubkey(cert, privateKey) == 1) {
- if (_addSubjectName(cert, subjectName) == true) {
- if (_addExtensions(cert) == true) {
- if (_addKeyIdentifier(cert) == true) {
- // The certificate is complete, sign it.
- if (X509_sign(cert, privateKey, EVP_sha256())) {
- result = true;
- } else {
- printf("error: (%d) %s\n", res, ERR_lib_error_string(res));
- }
- }
- }
- }
+ }
+ if (result) {
+ // add serial number
+ if (_addRandomSerial(cert) == true) {
+ if (_addValidityPeriod(cert, validityDays) == true) {
+ if (X509_set_pubkey(cert, privateKey) == 1) {
+ if (_addSubjectName(cert, subjectName) == true) {
+ if (_addExtensions(cert) == true) {
+ if (_addKeyIdentifier(cert) == true) {
+ // The certificate is complete, sign it.
+ if (X509_sign(cert, privateKey, EVP_sha256())) {
+ result = true;
+ } else {
+ printf("error: (%d) %s\n", res, ERR_lib_error_string(res));
}
+ }
}
+ }
}
+ }
}
+ }
- ERR_print_errors_fp(stdout);
+ ERR_print_errors_fp(stdout);
- BN_free(pub_exp);
+ BN_free(pub_exp);
- uint8_t *certificateDerEncoding = NULL;
- int numBytes = i2d_X509(cert, &certificateDerEncoding);
- if (numBytes < 0) {
- EVP_PKEY_free(privateKey);
- RSA_free(rsa);
- X509_free(cert);
+ uint8_t *certificateDerEncoding = NULL;
+ int numBytes = i2d_X509(cert, &certificateDerEncoding);
+ if (numBytes < 0) {
+ EVP_PKEY_free(privateKey);
+ RSA_free(rsa);
+ X509_free(cert);
- return NULL;
- }
+ return NULL;
+ }
- PARCBuffer *derBuffer = parcBuffer_Allocate(numBytes);
- parcBuffer_Flip(parcBuffer_PutArray(derBuffer, numBytes, certificateDerEncoding));
+ PARCBuffer *derBuffer = parcBuffer_Allocate(numBytes);
+ parcBuffer_Flip(parcBuffer_PutArray(derBuffer, numBytes, certificateDerEncoding));
- PARCX509Certificate *certificate = parcX509Certificate_CreateFromDERBuffer(derBuffer);
- parcBuffer_Release(&derBuffer);
+ PARCX509Certificate *certificate = parcX509Certificate_CreateFromDERBuffer(derBuffer);
+ parcBuffer_Release(&derBuffer);
- uint8_t *privateKeyBytes = NULL;
- int privateKeyByteCount = i2d_PrivateKey(privateKey, &privateKeyBytes);
- if (privateKeyByteCount < 0) {
- EVP_PKEY_free(privateKey);
- RSA_free(rsa);
- X509_free(cert);
+ uint8_t *privateKeyBytes = NULL;
+ int privateKeyByteCount = i2d_PrivateKey(privateKey, &privateKeyBytes);
+ if (privateKeyByteCount < 0) {
+ EVP_PKEY_free(privateKey);
+ RSA_free(rsa);
+ X509_free(cert);
- return NULL;
+ return NULL;
+ }
+
+ *privateKeyBuffer = parcBuffer_Allocate(privateKeyByteCount);
+ parcBuffer_Flip(parcBuffer_PutArray(*privateKeyBuffer, privateKeyByteCount, privateKeyBytes));
+
+ EVP_PKEY_free(privateKey);
+ RSA_free(rsa);
+ X509_free(cert);
+
+ return certificate;
+}
+
+static inline int _get_EC_params_from_lenght(int keyLength)
+{
+ //For the moment only support 256bit key length
+ switch (keyLength)
+ {
+ case 160:
+ return NID_secp160k1;
+ case 192:
+ return NID_secp192k1;
+ case 224:
+ return NID_secp224k1;
+ case 256:
+ return NID_secp256k1;
+ default:
+ return -1;
+ }
+
+}
+
+PARCX509Certificate * _createSelfSignedCertificate_EC(PARCBuffer **privateKeyBuffer, char *subjectName, int keyLength, size_t validityDays)
+{
+ parcSecurity_AssertIsInitialized();
+ int curve_params = _get_EC_params_from_lenght(keyLength);
+ bool result = false;
+
+ if (curve_params == -1)
+ return NULL;
+
+ EC_KEY *ec_key = EC_KEY_new_by_curve_name(curve_params);
+ assertNotNull(ec_key, "EC key creation failed.");
+
+ EC_KEY_set_asn1_flag(ec_key, OPENSSL_EC_NAMED_CURVE);
+
+ EVP_PKEY *pkey = EVP_PKEY_new();
+ assertNotNull(pkey, "EVP_PKEY_new() failed.");
+
+ X509 *cert = X509_new();
+ assertNotNull(cert, "X509_new() failed.");
+
+ int res;
+
+
+ if((res = (EC_KEY_generate_key(ec_key))) < 0 )
+ printf("error: (%d) %s\n", res, ERR_lib_error_string(res));
+ else if((res = (EVP_PKEY_set1_EC_KEY(pkey, ec_key))) < 0 )
+ printf("error: (%d) %s\n", res, ERR_lib_error_string(res));
+ else if (X509_set_version(cert, 2)) { // 2 => X509v3
+ result = true;
+ }
+
+ if (result) {
+ // add serial number
+ if (_addRandomSerial(cert) == true) {
+ if (_addValidityPeriod(cert, validityDays) == true) {
+ if (X509_set_pubkey(cert, pkey) == 1) {
+ if (_addSubjectName(cert, subjectName) == true) {
+ if (_addExtensions(cert) == true) {
+ if (_addKeyIdentifier(cert) == true) {
+ // The certificate is complete, sign it.
+ if (X509_sign(cert, pkey, EVP_sha256())) {
+ result = true;
+ } else {
+ printf("error: (%d) %s\n", res, ERR_lib_error_string(res));
+ }
+ }
+ }
+ }
+ }
+ }
}
+ }
- *privateKeyBuffer = parcBuffer_Allocate(privateKeyByteCount);
- parcBuffer_Flip(parcBuffer_PutArray(*privateKeyBuffer, privateKeyByteCount, privateKeyBytes));
+ ERR_print_errors_fp(stdout);
- return certificate;
+
+
+ uint8_t *certificateDerEncoding = NULL;
+ int numBytes = i2d_X509(cert, &certificateDerEncoding);
+ if (numBytes < 0) {
+ EVP_PKEY_free(pkey);
+ EC_KEY_free(ec_key);
+ X509_free(cert);
+
+ return NULL;
+ }
+
+ PARCBuffer *derBuffer = parcBuffer_Allocate(numBytes);
+ parcBuffer_Flip(parcBuffer_PutArray(derBuffer, numBytes, certificateDerEncoding));
+
+ PARCX509Certificate *certificate = parcX509Certificate_CreateFromDERBuffer(derBuffer);
+ parcBuffer_Release(&derBuffer);
+
+ uint8_t *pkeyBytes = NULL;
+ int pkeyByteCount = i2d_PrivateKey(pkey, &pkeyBytes);
+ if (pkeyByteCount < 0) {
+ EVP_PKEY_free(pkey);
+ EC_KEY_free(ec_key);
+ X509_free(cert);
+
+ return NULL;
+ }
+
+ *privateKeyBuffer = parcBuffer_Allocate(pkeyByteCount);
+ parcBuffer_Flip(parcBuffer_PutArray(*privateKeyBuffer, pkeyByteCount, pkeyBytes));
+
+ EVP_PKEY_free(pkey);
+ EC_KEY_free(ec_key);
+ X509_free(cert);
+
+ return certificate;
+}
+
+PARCX509Certificate *
+parcX509Certificate_CreateSelfSignedCertificate(PARCBuffer **privateKeyBuffer, char *subjectName, int keyLength, size_t validityDays, PARCKeyType keyType)
+{
+ switch(keyType) {
+ case PARCKeyType_RSA:
+ return _createSelfSignedCertificate_RSA(privateKeyBuffer, subjectName, keyLength, validityDays);
+ case PARCKeyType_EC:
+ return _createSelfSignedCertificate_EC(privateKeyBuffer, subjectName, keyLength, validityDays);
+ }
+
+ return NULL;
}