3rdparties/software/cl+ssl-20200427-git/src/random.lisp (1606 bytes)
1 ;;;; -*- Mode: LISP; Syntax: COMMON-LISP; indent-tabs-mode: nil; coding: utf-8; show-trailing-whitespace: t -*- 2 3 #+xcvb 4 (module 5 (:depends-on ("package" "conditions" "ffi" 6 (:cond ((:featurep :clisp) "ffi-buffer-clisp") 7 (t "ffi-buffer")) 8 "ffi-buffer-all"))) 9 10 (in-package :cl+ssl) 11 12 (defun random-bytes (count) 13 "Generates COUNT cryptographically strong pseudo-random bytes. Returns 14 the bytes as a SIMPLE-ARRAY with ELEMENT-TYPE '(UNSIGNED-BYTE 8). Signals 15 an ERROR in case of problems, for example when the OpenSSL random number 16 generator has not been seeded with enough randomness to ensure an 17 unpredictable byte sequence." 18 (let* ((result (make-array count :element-type '(unsigned-byte 8))) 19 (buf (make-buffer count)) 20 (ret (with-pointer-to-vector-data (ptr buf) 21 (rand-bytes ptr count)))) 22 (when (/= 1 ret) 23 (error "RANDOM-BYTES failed: error reported by the OpenSSL RAND_bytes function. ~A." 24 (format-ssl-error-queue nil (read-ssl-error-queue)))) 25 (s/b-replace result buf))) 26 27 ;; TODO: Should we define random-specific constants and condition classes for 28 ;; RAND_F_RAND_GET_RAND_METHOD, RAND_F_SSLEAY_RAND_BYTES, RAND_R_PRNG_NOT_SEEDED 29 ;; (defined in the rand.h file of the OpenSSl sources)? 30 ;; Where to place these constants/condtitions, here or in the conditions.lisp? 31 ;; On the other hand, those constants are just numbers defined for C, 32 ;; for now we jsut report human readable strings, without possibility 33 ;; to distinguish these error causes programmatically.