Blame usr/lib/common/cert.c

Packit 8681c6
/*
Packit 8681c6
 * COPYRIGHT (c) International Business Machines Corp. 2001-2017
Packit 8681c6
 *
Packit 8681c6
 * This program is provided under the terms of the Common Public License,
Packit 8681c6
 * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
Packit 8681c6
 * software constitutes recipient's acceptance of CPL-1.0 terms which can be
Packit 8681c6
 * found in the file LICENSE file or at
Packit 8681c6
 * https://opensource.org/licenses/cpl1.0.php
Packit 8681c6
 */
Packit 8681c6
Packit 8681c6
// File:  cert.c
Packit 8681c6
//
Packit 8681c6
// Functions contained within:
Packit 8681c6
//
Packit 8681c6
//    cert_check_required_attributes
Packit 8681c6
//    cert_validate_attribute
Packit 8681c6
//    cert_x509_check_required_attributes
Packit 8681c6
//    cert_x509_set_default_attributes
Packit 8681c6
//    cert_x509_validate_attribute
Packit 8681c6
//    cert_vendor_check_required_attributes
Packit 8681c6
//    cert_vendor_validate_attribute
Packit 8681c6
//
Packit 8681c6
Packit 8681c6
#include <pthread.h>
Packit 8681c6
#include <stdlib.h>
Packit 8681c6
Packit 8681c6
#include <string.h>             // for memcmp() et al
Packit 8681c6
Packit 8681c6
#include "pkcs11types.h"
Packit 8681c6
#include "defs.h"
Packit 8681c6
#include "host_defs.h"
Packit 8681c6
#include "h_extern.h"
Packit 8681c6
#include "trace.h"
Packit 8681c6
Packit 8681c6
Packit 8681c6
// cert_check_required_attributes
Packit 8681c6
//
Packit 8681c6
// Checks for required attributes for generic CKO_CERTIFICATE objects
Packit 8681c6
//
Packit 8681c6
//    CKA_CERTIFICATE_TYPE : must be present on MODE_CREATE.
Packit 8681c6
//
Packit 8681c6
CK_RV cert_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
Packit 8681c6
{
Packit 8681c6
    CK_ATTRIBUTE *attr = NULL;
Packit 8681c6
    CK_BBOOL found;
Packit 8681c6
Packit 8681c6
    if (!tmpl)
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
Packit 8681c6
    if (mode == MODE_CREATE) {
Packit 8681c6
        found = template_attribute_find(tmpl, CKA_CERTIFICATE_TYPE, &attr);
Packit 8681c6
        if (found == FALSE) {
Packit 8681c6
            TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
Packit 8681c6
            return CKR_TEMPLATE_INCOMPLETE;
Packit 8681c6
        }
Packit 8681c6
        // don't bother checking the value.  it was checked in the 'validate'
Packit 8681c6
        // routine.
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    return template_check_required_base_attributes(tmpl, mode);
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
// cert_validate_attribute()
Packit 8681c6
//
Packit 8681c6
CK_RV cert_validate_attribute(TEMPLATE *tmpl, CK_ATTRIBUTE *attr,
Packit 8681c6
                              CK_ULONG mode)
Packit 8681c6
{
Packit 8681c6
    CK_CERTIFICATE_TYPE type;
Packit 8681c6
Packit 8681c6
    switch (attr->type) {
Packit 8681c6
    case CKA_CERTIFICATE_TYPE:
Packit 8681c6
        if (mode != MODE_CREATE) {
Packit 8681c6
            TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
Packit 8681c6
            return CKR_ATTRIBUTE_READ_ONLY;
Packit 8681c6
        }
Packit 8681c6
        type = *(CK_CERTIFICATE_TYPE *) attr->pValue;
Packit 8681c6
        if (type == CKC_X_509 || type >= CKC_VENDOR_DEFINED) {
Packit 8681c6
            return CKR_OK;
Packit 8681c6
        }
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
Packit 8681c6
        return CKR_ATTRIBUTE_VALUE_INVALID;
Packit 8681c6
    default:
Packit 8681c6
        return template_validate_base_attribute(tmpl, attr, mode);
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
// cert_x509_check_required_attributes()
Packit 8681c6
//
Packit 8681c6
CK_RV cert_x509_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
Packit 8681c6
{
Packit 8681c6
    CK_ATTRIBUTE *attr = NULL;
Packit 8681c6
    CK_BBOOL found;
Packit 8681c6
Packit 8681c6
    found = template_attribute_find(tmpl, CKA_SUBJECT, &attr);
Packit 8681c6
    if (!found) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
Packit 8681c6
        return CKR_TEMPLATE_INCOMPLETE;
Packit 8681c6
    }
Packit 8681c6
    found = template_attribute_find(tmpl, CKA_VALUE, &attr);
Packit 8681c6
    if (!found) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
Packit 8681c6
        return CKR_TEMPLATE_INCOMPLETE;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    return cert_check_required_attributes(tmpl, mode);
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
// cert_x509_set_default_attributes()
Packit 8681c6
//
Packit 8681c6
// Set the default attributes for X.509 certificates
Packit 8681c6
//
Packit 8681c6
//    CKA_ID            : empty string
Packit 8681c6
//    CKA_ISSUER        : empty string
Packit 8681c6
//    CKA_SERIAL_NUMBER : empty string
Packit 8681c6
//
Packit 8681c6
CK_RV cert_x509_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
Packit 8681c6
{
Packit 8681c6
    CK_ATTRIBUTE *id_attr = NULL;
Packit 8681c6
    CK_ATTRIBUTE *issuer_attr = NULL;
Packit 8681c6
    CK_ATTRIBUTE *serial_attr = NULL;
Packit 8681c6
Packit 8681c6
    // satisfy compiler warning....
Packit 8681c6
    //
Packit 8681c6
    if (mode)
Packit 8681c6
        id_attr = NULL;
Packit 8681c6
Packit 8681c6
    id_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
Packit 8681c6
    issuer_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
Packit 8681c6
    serial_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
Packit 8681c6
Packit 8681c6
    if (!id_attr || !issuer_attr || !serial_attr) {
Packit 8681c6
        if (id_attr)
Packit 8681c6
            free(id_attr);
Packit 8681c6
        if (issuer_attr)
Packit 8681c6
            free(issuer_attr);
Packit 8681c6
        if (serial_attr)
Packit 8681c6
            free(serial_attr);
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
Packit 8681c6
Packit 8681c6
        return CKR_HOST_MEMORY;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    id_attr->type = CKA_ID;
Packit 8681c6
    id_attr->ulValueLen = 0;    // empty string
Packit 8681c6
    id_attr->pValue = NULL;
Packit 8681c6
Packit 8681c6
    issuer_attr->type = CKA_ISSUER;
Packit 8681c6
    issuer_attr->ulValueLen = 0;        // empty byte array
Packit 8681c6
    issuer_attr->pValue = NULL;
Packit 8681c6
Packit 8681c6
    serial_attr->type = CKA_SERIAL_NUMBER;
Packit 8681c6
    serial_attr->ulValueLen = 0;        // empty byte array
Packit 8681c6
    serial_attr->pValue = NULL;
Packit 8681c6
Packit 8681c6
    template_update_attribute(tmpl, id_attr);
Packit 8681c6
    template_update_attribute(tmpl, issuer_attr);
Packit 8681c6
    template_update_attribute(tmpl, serial_attr);
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
// cert_x509_validate_attributes()
Packit 8681c6
//
Packit 8681c6
CK_RV cert_x509_validate_attribute(TEMPLATE *tmpl, CK_ATTRIBUTE *attr,
Packit 8681c6
                                   CK_ULONG mode)
Packit 8681c6
{
Packit 8681c6
    switch (attr->type) {
Packit 8681c6
    case CKA_SUBJECT:
Packit 8681c6
        if (mode != MODE_CREATE) {
Packit 8681c6
            TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
Packit 8681c6
            return CKR_ATTRIBUTE_READ_ONLY;
Packit 8681c6
        }
Packit 8681c6
        return CKR_OK;
Packit 8681c6
    case CKA_ID:
Packit 8681c6
    case CKA_ISSUER:
Packit 8681c6
    case CKA_SERIAL_NUMBER:
Packit 8681c6
        return CKR_OK;
Packit 8681c6
    case CKA_VALUE:
Packit 8681c6
        if (mode != MODE_CREATE) {
Packit 8681c6
            TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
Packit 8681c6
            return CKR_ATTRIBUTE_READ_ONLY;
Packit 8681c6
        }
Packit 8681c6
        return CKR_OK;
Packit 8681c6
    default:
Packit 8681c6
        return cert_validate_attribute(tmpl, attr, mode);
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
// cert_vendor_check_required_attributes()
Packit 8681c6
//
Packit 8681c6
CK_RV cert_vendor_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
Packit 8681c6
{
Packit 8681c6
    // CKC_VENDOR has no required attributes
Packit 8681c6
    //
Packit 8681c6
    return cert_check_required_attributes(tmpl, mode);
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
// cert_vendor_validate_attribute()
Packit 8681c6
//
Packit 8681c6
CK_RV cert_vendor_validate_attribute(TEMPLATE *tmpl, CK_ATTRIBUTE *attr,
Packit 8681c6
                                     CK_ULONG mode)
Packit 8681c6
{
Packit 8681c6
    // cryptoki specifies no attributes for CKC_VENDOR certificates
Packit 8681c6
    //
Packit 8681c6
    return cert_validate_attribute(tmpl, attr, mode);
Packit 8681c6
}