├── package.lisp ├── tests.lisp ├── secret-values.asd ├── LICENSE ├── secret-values.lisp └── README /package.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:secret-values 2 | (:use #:common-lisp) 3 | (:export 4 | #:secret-value 5 | #:secret-value-p 6 | #:conceal-value 7 | #:reveal-value 8 | #:ensure-value-concealed 9 | #:ensure-value-revealed)) 10 | -------------------------------------------------------------------------------- /tests.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:secret-values-tests 2 | (:use #:common-lisp #:secret-values)) 3 | 4 | (in-package #:secret-values-tests) 5 | 6 | (defparameter *password* (conceal-value "secret password")) 7 | 8 | (defun test () 9 | (reveal-value *password*)) 10 | -------------------------------------------------------------------------------- /secret-values.asd: -------------------------------------------------------------------------------- 1 | (defsystem #:secret-values 2 | :name "secret-values" 3 | :licence "MIT" 4 | :description "Secret values is a Common Lisp library designed to 5 | reduce the risk of accidentally revealing secret values such as 6 | passwords." 7 | :author "Thomas Bakketun " 8 | :depends-on () 9 | :serial t 10 | :components ((:file "package") 11 | (:file "secret-values"))) 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (This is the MIT / X Consortium license as taken from 2 | http://www.opensource.org/licenses/mit-license.html) 3 | 4 | Copyright (c) 2013 Thomas Bakketun 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | "Software"), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /secret-values.lisp: -------------------------------------------------------------------------------- 1 | (in-package :secret-values) 2 | 3 | 4 | (defstruct secret-value 5 | (name) 6 | (symbol)) 7 | 8 | 9 | (defmethod print-object ((object secret-value) stream) 10 | (if (secret-value-name object) 11 | (print-unreadable-object (object stream :type t :identity t) 12 | (princ (secret-value-name object) stream)) 13 | (print-unreadable-object (object stream :type t :identity t)))) 14 | 15 | 16 | (defun conceal-value (value &key name) 17 | "Conceals value into a SECRET-VALUE object. An optional name can be 18 | provided to aid debugging." 19 | (let ((symbol (gensym (if (stringp name) 20 | name 21 | "")))) 22 | (setf (get symbol 'secret) (lambda () value)) 23 | (make-secret-value :name name :symbol symbol))) 24 | 25 | 26 | (defun reveal-value (secret-value) 27 | "Returns the value in SECRET-VALUE. An error of type TYPE-ERROR is 28 | signalled if the argument is not of type SECRET-VALUES." 29 | (funcall (get (secret-value-symbol secret-value) 'secret))) 30 | 31 | 32 | (defun ensure-value-concealed (object &key name) 33 | "If object is already a of type SECRET-VALUE returns is unaltered, 34 | otherwise conceals it as if by calling CONCEAL-VALUE." 35 | (typecase object 36 | (secret-value object) 37 | (t (conceal-value object :name name)))) 38 | 39 | 40 | (defun ensure-value-revealed (object) 41 | "If object is type SECRET-VALUE returns the concealed value, otherwise returns object." 42 | (typecase object 43 | (secret-value (reveal-value object)) 44 | (t object))) 45 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Secret values is a Common Lisp library designed to reduce the risk of 2 | accidentally revealing secret values such as passwords. 3 | 4 | Source code at https://github.com/rotatef/secret-values 5 | 6 | Applications will often have to deal with values that should be kept 7 | secret, e.g. a password for accessing the applications database. There 8 | will allways be a risk that such a secret value is accidentally 9 | revealed e.g. in a backtrace or log file. Fixing this can be difficult 10 | because the code that generates the backtrace or log is often not part 11 | of the application. Turning off logging or backtrace is seldom an 12 | option. Making sure that logs and backtrace are kept secure can also 13 | be difficult. 14 | 15 | This library provides a simple wrapper type that can be used to 16 | conceal secret data. This wrapper tries to keep it's value secret by 17 | overriding print-object and some other tricks. In order to get the 18 | full benefits, the value should be concealed as early as possible and 19 | revealed as late as possible. For example, a database library should 20 | accept the password as a concealed value and only reveal it just 21 | before it's used to authenticate with the database. This will greatly 22 | reduce the risk of the password ending up in a log file or backtrace. 23 | 24 | All symbols are exported from the package SECRET-VALUES. 25 | 26 | The function CONCEAL-VALUE wraps a value into an object of type 27 | SECRET-VALUE. An optional name can be provided. The name is intended 28 | for debugging only and is included when the object is printed. 29 | 30 | To get the value back, call REVEAL-VALUE. 31 | 32 | The function ENSURE-VALUE-REVEALED behaves like REAVEAL-VALUE when 33 | called with an argument of type SECRET-VALUE, otherwise it just 34 | returns it's argument verbatim. This makes it easy to write code that 35 | accepts both secret and plaintext values. 36 | --------------------------------------------------------------------------------