示例#1
0
static int
_parcPkcs12KeyStore_ParseFile(PARCPkcs12KeyStore *keystore, const char *filename, const char *password)
{
    parcSecurity_AssertIsInitialized();

    FILE *fp = fopen(filename, "rb");

    assertNotNull(fp, "Error opening %s: %s", filename, strerror(errno));
    if (fp == NULL) {
        return -1;
    }

    PKCS12 *p12Keystore = NULL;
    d2i_PKCS12_fp(fp, &p12Keystore);
    fclose(fp);

    int success = PKCS12_parse(p12Keystore, password, &keystore->private_key, &keystore->x509_cert, NULL);
    PKCS12_free(p12Keystore);

    if (!success) {
        unsigned long errcode;
        while ((errcode = ERR_get_error()) != 0) {
            fprintf(stderr, "openssl error: %s\n", ERR_error_string(errcode, NULL));
        }
        return -1;
    }

    keystore->public_key = X509_get_pubkey(keystore->x509_cert);
    return 0;
}
示例#2
0
LONGBOW_TEST_CASE(Global, parcSecurity_IsInitialized)
{
    parcSecurity_Init();
    parcSecurity_AssertIsInitialized();
    parcSecurity_Fini();
    assertFalse(parcSecurity_IsInitialized(), "parcSecurity_IsInitialized should be false now");
}
示例#3
0
static PARCSignature *
_SignDigest(PARCPublicKeySigner *signer, const PARCCryptoHash *digestToSign)
{
    parcSecurity_AssertIsInitialized();

    assertNotNull(signer, "Parameter must be non-null CCNxFileKeystore");
    assertNotNull(digestToSign, "Buffer to sign must not be null");

    // TODO: what is the best way to expose this?
    PARCKeyStore *keyStore = signer->keyStore;
    PARCBuffer *privateKeyBuffer = parcKeyStore_GetDEREncodedPrivateKey(keyStore);
    EVP_PKEY *privateKey = NULL;
    size_t keySize = parcBuffer_Remaining(privateKeyBuffer);
    uint8_t *bytes = parcBuffer_Overlay(privateKeyBuffer, keySize);
    privateKey = d2i_PrivateKey(EVP_PKEY_RSA, &privateKey, (const unsigned char **) &bytes, keySize);
    parcBuffer_Release(&privateKeyBuffer);

    RSA *rsa = EVP_PKEY_get1_RSA(privateKey);

    int opensslDigestType;

    switch (parcCryptoHash_GetDigestType(digestToSign)) {
        case PARCCryptoHashType_SHA256:
            opensslDigestType = NID_sha256;
            break;
        case PARCCryptoHashType_SHA512:
            opensslDigestType = NID_sha512;
            break;
        default:
            trapUnexpectedState("Unknown digest type: %s",
                                parcCryptoHashType_ToString(parcCryptoHash_GetDigestType(digestToSign)));
    }

    uint8_t *sig = parcMemory_Allocate(RSA_size(rsa));
    assertNotNull(sig, "parcMemory_Allocate(%u) returned NULL", RSA_size(rsa));

    unsigned sigLength = 0;
    PARCBuffer *bb_digest = parcCryptoHash_GetDigest(digestToSign);
    int result = RSA_sign(opensslDigestType,
                          (unsigned char *) parcByteArray_Array(parcBuffer_Array(bb_digest)),
                          (int) parcBuffer_Remaining(bb_digest),
                          sig,
                          &sigLength,
                          rsa);
    assertTrue(result == 1, "Got error from RSA_sign: %d", result);
    RSA_free(rsa);

    PARCBuffer *bbSign = parcBuffer_Allocate(sigLength);
    parcBuffer_Flip(parcBuffer_PutArray(bbSign, sigLength, sig));
    parcMemory_Deallocate((void **) &sig);

    PARCSignature *signature =
    parcSignature_Create(_GetSigningAlgorithm(signer),
                         parcCryptoHash_GetDigestType(digestToSign),
                         bbSign
                         );
    parcBuffer_Release(&bbSign);
    return signature;
}
示例#4
0
static PARCCryptoHash *
_GetCertificateDigest(PARCPkcs12KeyStore *keystore)
{
    parcSecurity_AssertIsInitialized();

    assertNotNull(keystore, "Parameter must be non-null PARCPkcs12KeyStore");

    if (keystore->certificate_digest == NULL) {
        uint8_t digestBuffer[SHA256_DIGEST_LENGTH];
        int result = X509_digest(keystore->x509_cert, EVP_sha256(), digestBuffer, NULL);
        if (result) {
            keystore->certificate_digest =
                parcBuffer_Flip(parcBuffer_PutArray(parcBuffer_Allocate(SHA256_DIGEST_LENGTH), SHA256_DIGEST_LENGTH, digestBuffer));
        }
    }

    PARCCryptoHash *hash = parcCryptoHash_Create(PARC_HASH_SHA256, keystore->certificate_digest);
    return hash;
}
示例#5
0
static PARCCryptoHash *
_GetPublickKeyDigest(PARCPkcs12KeyStore *keystore)
{
    parcSecurity_AssertIsInitialized();

    assertNotNull(keystore, "Parameter must be non-null PARCPkcs12KeyStore");

    if (keystore->public_key_digest == NULL) {
        AUTHORITY_KEYID  *akid = X509_get_ext_d2i(keystore->x509_cert, NID_authority_key_identifier, NULL, NULL);
        if (akid != NULL) {
            ASN1_OCTET_STRING *skid = X509_get_ext_d2i(keystore->x509_cert, NID_subject_key_identifier, NULL, NULL);
            if (skid != NULL) {
                keystore->public_key_digest =
                    parcBuffer_PutArray(parcBuffer_Allocate(skid->length), skid->length, skid->data);
                parcBuffer_Flip(keystore->public_key_digest);
                ASN1_OCTET_STRING_free(skid);
            }
            AUTHORITY_KEYID_free(akid);
        }
    }

    // If we could not load the digest from the certificate, then calculate it from the public key.
    if (keystore->public_key_digest == NULL) {
        uint8_t digestBuffer[SHA256_DIGEST_LENGTH];

        int result = ASN1_item_digest(ASN1_ITEM_rptr(X509_PUBKEY),
                                      EVP_sha256(),
                                      X509_get_X509_PUBKEY(keystore->x509_cert),
                                      digestBuffer,
                                      NULL);
        if (result != 1) {
            assertTrue(0, "Could not compute digest over certificate public key");
        } else {
            keystore->public_key_digest =
                parcBuffer_PutArray(parcBuffer_Allocate(SHA256_DIGEST_LENGTH), SHA256_DIGEST_LENGTH, digestBuffer);
            parcBuffer_Flip(keystore->public_key_digest);
        }
    }

    // This stores a reference, so keystore->public_key_digest will remain valid
    // even if the cryptoHasher is destroyed
    return parcCryptoHash_Create(PARC_HASH_SHA256, keystore->public_key_digest);
}
示例#6
0
static PARCBuffer *
_GetDEREncodedPrivateKey(PARCPkcs12KeyStore *keystore)
{
    parcSecurity_AssertIsInitialized();

    assertNotNull(keystore, "Parameter must be non-null PARCPkcs12KeyStore");

    if (keystore->private_key_der == NULL) {
        uint8_t *der = NULL;

        // this allocates memory for der
        int derLength = i2d_PrivateKey(keystore->private_key, &der);
        if (derLength > 0) {
            keystore->private_key_der =
            parcBuffer_Flip(parcBuffer_PutArray(parcBuffer_Allocate(derLength), derLength, der));
        }
        OPENSSL_free(der);
    }

    return parcBuffer_Copy(keystore->private_key_der);
}
示例#7
0
// =============================================================
LONGBOW_STOP_DEPRECATED_WARNINGS
// =============================================================

bool
parcPkcs12KeyStore_CreateFile(
    const char *filename,
    const char *password,
    const char *subjectName,
    unsigned keyLength,
    unsigned validityDays)
{
    parcSecurity_AssertIsInitialized();

    bool result = false;

    PARCCertificateFactory *factory = parcCertificateFactory_Create(PARCCertificateType_X509, PARCContainerEncoding_DER);

    PARCBuffer *privateKeyBuffer;
    PARCCertificate *certificate = parcCertificateFactory_CreateSelfSignedCertificate(factory, &privateKeyBuffer, (char *) subjectName, keyLength, validityDays);

    parcCertificateFactory_Release(&factory);

    if (certificate != NULL) {
        // construct the full PKCS12 keystore to hold the certificate and private key

        // Extract the private key
        EVP_PKEY *privateKey = NULL;
        uint8_t *privateKeyBytes = parcBuffer_Overlay(privateKeyBuffer, parcBuffer_Limit(privateKeyBuffer));
        d2i_PrivateKey(EVP_PKEY_RSA, &privateKey, (const unsigned char **) &privateKeyBytes, parcBuffer_Limit(privateKeyBuffer));
        parcBuffer_Release(&privateKeyBuffer);

        // Extract the certificate
        PARCBuffer *certBuffer = parcCertificate_GetDEREncodedCertificate(certificate);
        uint8_t *certBytes = parcBuffer_Overlay(certBuffer, parcBuffer_Limit(certBuffer));
        X509 *cert = NULL;
        d2i_X509(&cert, (const unsigned char **) &certBytes, parcBuffer_Limit(certBuffer));

        parcCertificate_Release(&certificate);

        PKCS12 *pkcs12 = PKCS12_create((char *) password,
                                       "ccnxuser",
                                       privateKey,
                                       cert,
                                       NULL,
                                       0,
                                       0,
                                       0 /*default iter*/,
                                       PKCS12_DEFAULT_ITER /*mac_iter*/,
                                       0);

        if (pkcs12 != NULL) {
            int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0600);
            if (fd != -1) {
                FILE *fp = fdopen(fd, "wb");
                if (fp != NULL) {
                    i2d_PKCS12_fp(fp, pkcs12);
                    fclose(fp);
                    result = true;
                } else {
                    trapUnrecoverableState("Cannot fdopen(3) the file descriptor %d", fd);
                }
                close(fd);
            } else {
                trapUnrecoverableState("Cannot open(2) the file '%s': %s", filename, strerror(errno));
            }
            PKCS12_free(pkcs12);
            X509_free(cert);
            EVP_PKEY_free(privateKey);
        } else {
            unsigned long errcode;
            while ((errcode = ERR_get_error()) != 0) {
                fprintf(stderr, "openssl error: %s\n", ERR_error_string(errcode, NULL));
            }
            trapUnrecoverableState("PKCS12_create returned a NULL value.");
        }
    }

    return result;
}
示例#8
0
LONGBOW_TEST_CASE(Global, parcSecurity_Init)
{
    parcSecurity_Init();
    parcSecurity_AssertIsInitialized();
    parcSecurity_Fini();
}