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; };
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; }