static int establish_symmetric_cipher(struct openssl_session_auth_context* ctx, const char* client_certificate, int client_certificate_length) {
    int ret = 0;
    char symmetric_key[MAX_SANE_KEY_LENGTH];
    char* encrypted_data = NULL;
    int encrypted_length;


    get_random_key(symmetric_key, module_context->symmetric_cipher.key_length);

    if ( encrypt_data(client_certificate, client_certificate_length, symmetric_key, module_context->symmetric_cipher.key_length, &encrypted_data, &encrypted_length) ) {
        printf("Failed to encrypt symmetric key\n");
        goto failed;
    }

    if ( write_u32(ctx, encrypted_length) != 4 ) {
        printf("Failed to send encrypted key length\n");
        goto failed;
    }

    if ( openssl_local_write(ctx, encrypted_data, encrypted_length) != encrypted_length ) {
        printf("Failed to encrypted symmetric key\n");
        goto failed;
    }

    if ( write_u32(ctx,  strlen(module_context->symmetric_cipher.kernel_cipher_name) + 1) != 4 ) {
        printf("Failed to send alg name length\n");
        goto failed;
    }

    /* Set encryptor before sending last message to the client so that we are ready to encrypted enc messages when the auth protocol is done */
    ctx->fid->conn->encryptor = new_openssl_crypt(module_context->symmetric_cipher.openssl_cipher_name, symmetric_key, module_context->symmetric_cipher.key_length);

    if ( openssl_local_write(ctx, module_context->symmetric_cipher.kernel_cipher_name, strlen(module_context->symmetric_cipher.kernel_cipher_name) + 1) < 0) {
        printf("Failed to send symmetric cipher name\n");
        goto failed;
    }

    goto done;
failed:
    ret = -1;
done:
    free(encrypted_data);
    return ret;
}
static int verify_private_key_ownership(struct openssl_session_auth_context* ctx, const char* private_key, int private_key_length, const char* client_certificate, int client_certificate_length) {
    char* x_buffer = NULL, *y_buffer = NULL, *concat_buffer = NULL;
    int ret, tmp;
    char* yx_signature = NULL, *xy_signature = NULL;
    int yx_signature_length, xy_signature_length;

    x_buffer = malloc(XY_RANDOM_DATA_LENGTH);
    y_buffer = malloc(XY_RANDOM_DATA_LENGTH);
    concat_buffer = malloc(2*XY_RANDOM_DATA_LENGTH);
    if ( !x_buffer || !y_buffer || !concat_buffer )
        goto failed;

    get_random_key(x_buffer, XY_RANDOM_DATA_LENGTH);

    if ( write_u32(ctx, XY_RANDOM_DATA_LENGTH) != 4 ) {
        printf("Failed to x buffer size\n");
        goto failed;
    }

    if ( openssl_local_write(ctx, x_buffer, XY_RANDOM_DATA_LENGTH) != XY_RANDOM_DATA_LENGTH ) {
        printf("Failed to send x buffer\n");
        goto failed;
    }

    if ( openssl_local_read(ctx, XY_RANDOM_DATA_LENGTH, y_buffer, &tmp) < XY_RANDOM_DATA_LENGTH ) {
        printf( "Failed to read y buffer\n");
        goto failed;
    }

    memcpy(concat_buffer,y_buffer, XY_RANDOM_DATA_LENGTH);
    memcpy(concat_buffer+XY_RANDOM_DATA_LENGTH,x_buffer, XY_RANDOM_DATA_LENGTH);

    yx_signature_length = read_u32(ctx);
    if ( yx_signature_length == READ_ERROR ) {
        printf("Failed to read yx signature length\n");
        goto failed;
    }

    yx_signature = malloc(yx_signature_length);
    if ( !yx_signature )
        goto failed;

    if ( openssl_local_read(ctx,  yx_signature_length, yx_signature, &tmp) < yx_signature_length ) {
        printf("Failed to read yx signature\n");
        goto failed;
    }

    ret = verify_signature(client_certificate, client_certificate_length, concat_buffer, 2*XY_RANDOM_DATA_LENGTH, yx_signature, yx_signature_length);
    if ( ret ) {
        printf("Failed to verify yx signature\n");
        goto failed;
    }

    memcpy(concat_buffer,x_buffer, XY_RANDOM_DATA_LENGTH);
    memcpy(concat_buffer+XY_RANDOM_DATA_LENGTH,y_buffer, XY_RANDOM_DATA_LENGTH);

    ret = sign_data(private_key, private_key_length, concat_buffer, 2*XY_RANDOM_DATA_LENGTH, &xy_signature, &xy_signature_length);
    if ( ret ) {
        printf("Failed to sign xy buffer\n");
        goto failed;
    }

    if ( write_u32(ctx, xy_signature_length) != 4) {
        printf("Failed to send xy signature length\n");
        goto failed;
    }

    /* Send server certificate */
    if ( openssl_local_write(ctx, xy_signature, xy_signature_length) != xy_signature_length ) {
        printf("Failed to send xy signature\n");
        goto failed;
    }

    goto done;
failed:
    ret = -1;
done:
    free(x_buffer);
    free(y_buffer);
    free(concat_buffer);
    free(xy_signature);
    free(yx_signature);
    return ret;
};
Example #3
0
int
SharedMemory_init(SharedMemory *self, PyObject *args, PyObject *keywords) {
    NoneableKey key;
    int mode = 0600;
    unsigned long size = 0;
    int shmget_flags = 0;
    int shmat_flags = 0;
    char init_character = ' ';
    char *keyword_list[ ] = {"key", "flags", "mode", "size", "init_character", NULL};
    PyObject *py_size = NULL;

    DPRINTF("Inside SharedMemory_init()\n");

    if (!PyArg_ParseTupleAndKeywords(args, keywords, "O&|iikc", keyword_list,
                                     &convert_key_param, &key,
                                     &shmget_flags, &mode, &size,
                                     &init_character))
        goto error_return;

    mode &= 0777;
    shmget_flags &= ~0777;

    DPRINTF("key is none = %d, key value = %ld\n", key.is_none, (long)key.value);

    if ( !(shmget_flags & IPC_CREAT) && (shmget_flags & IPC_EXCL) ) {
        PyErr_SetString(PyExc_ValueError,
                "IPC_EXCL must be combined with IPC_CREAT");
        goto error_return;
    }

    if (key.is_none && ((shmget_flags & IPC_EXCL) != IPC_EXCL)) {
        PyErr_SetString(PyExc_ValueError,
                "Key can only be None if IPC_EXCL is set");
        goto error_return;
    }

    // When creating a new segment, the default size is PAGE_SIZE.
    if (((shmget_flags & IPC_CREX) == IPC_CREX) && (!size))
        size = PAGE_SIZE;

    if (key.is_none) {
        // (key == None) ==> generate a key for the caller
        do {
            errno = 0;
            self->key = get_random_key();

            DPRINTF("Calling shmget, key=%ld, size=%lu, mode=%o, flags=0x%x\n",
                    (long)self->key, size, mode, shmget_flags);
            self->id = shmget(self->key, size, mode | shmget_flags);
        } while ( (-1 == self->id) && (EEXIST == errno) );
    }
    else {
        // (key != None) ==> use key supplied by the caller
        self->key = key.value;

        DPRINTF("Calling shmget, key=%ld, size=%lu, mode=%o, flags=0x%x\n",
                (long)self->key, size, mode, shmget_flags);
        self->id = shmget(self->key, size, mode | shmget_flags);
    }

    DPRINTF("id == %d\n", self->id);

    if (self->id == -1) {
        switch (errno) {
            case EACCES:
                PyErr_Format(pPermissionsException,
                             "Permission %o cannot be granted on the existing segment",
                             mode);
            break;

            case EEXIST:
                PyErr_Format(pExistentialException,
                    "Shared memory with the key %ld already exists",
                    (long)self->key);
            break;

            case ENOENT:
                PyErr_Format(pExistentialException,
                    "No shared memory exists with the key %ld", (long)self->key);
            break;

            case EINVAL:
                PyErr_SetString(PyExc_ValueError, "The size is invalid");
            break;

            case ENOMEM:
                PyErr_SetString(PyExc_MemoryError, "Not enough memory");
            break;

            case ENOSPC:
                PyErr_SetString(PyExc_OSError,
                    "Not enough shared memory identifiers available (ENOSPC)");
            break;

            default:
                PyErr_SetFromErrno(PyExc_OSError);
            break;
        }
        goto error_return;
    }

    // Attach the memory. If no write permissions requested, attach read-only.
    shmat_flags = (mode & 0200) ? 0 : SHM_RDONLY;
    if (NULL == shm_attach(self, NULL, shmat_flags)) {
        // Bad news, something went wrong.
        goto error_return;
    }

    if ( ((shmget_flags & IPC_CREX) == IPC_CREX) && (!(shmat_flags & SHM_RDONLY)) ) {
        // Initialize the memory.

        py_size = shm_get_value(self->id, SVIFP_SHM_SIZE);

        if (!py_size)
            goto error_return;
        else {
#if PY_MAJOR_VERSION > 2
            size = PyLong_AsUnsignedLongMask(py_size);
#else
            size = PyInt_AsUnsignedLongMask(py_size);
#endif

            DPRINTF("memsetting address %p to %lu bytes of ASCII 0x%x (%c)\n", \
                    self->address, size, (int)init_character, init_character);
            memset(self->address, init_character, size);
        }

        Py_DECREF(py_size);
    }

    return 0;

    error_return:
    return -1;
}