128 lines
3.2 KiB
VimL
128 lines
3.2 KiB
VimL
" Manage keys used for signing local configuration files
|
|
"
|
|
" * Can be disabled completely by setting VIM_NOCRYPTO in the environment
|
|
" * Will disable itself silently if openssl is unavailable
|
|
" * Keys will be looked up in g:vim_vardata/keys by default, unless
|
|
" g:vim_keys is set
|
|
|
|
|
|
" Register no-operation functions for signing and checking signatures
|
|
|
|
function! SignFile(filename,sigfile)
|
|
if !empty( glob( a:sigfile ) )
|
|
call delete( a:sigfile )
|
|
endif
|
|
return 0
|
|
endfunction
|
|
|
|
function! CheckSignature(filename,sigfile)
|
|
echoerr "Signature checking is disabled."
|
|
return 0
|
|
endfunction
|
|
|
|
|
|
" Get configured directory / use default. Make sure global configuration
|
|
" is cleared.
|
|
if exists( "g:vim_keys" )
|
|
if $VIM_NOCRYPTO == ""
|
|
let s:keys_dir = g:vim_keys
|
|
endif
|
|
unlet g:vim_keys
|
|
elseif $VIM_NOCRYPTO == "" && g:vim_vardata != ""
|
|
let s:keys_dir = g:vim_vardata . "/keys"
|
|
endif
|
|
if !exists( "s:keys_dir" ) || !executable( "openssl" ) || !has( "cryptv" )
|
|
finish
|
|
endif
|
|
|
|
" Try creating the directory
|
|
if ! CreateDirectoryIfNecessary( s:keys_dir )
|
|
echoerr "Could not create" s:keys_dir
|
|
\ "; signed configuration support disabled"
|
|
finish
|
|
endif
|
|
|
|
" Create the key if necessary
|
|
if !filereadable( s:keys_dir . "/vim.key" )
|
|
let s:key_bits = exists( "g:vim_key_bits" ) ? g:vim_key_bits : 4096
|
|
echo "Generating configuration signing key (" . s:key_bits
|
|
\ . " bits)..."
|
|
let s:genrsa = system( "openssl genrsa -out "
|
|
\ . shellescape( s:keys_dir . "/vim.key" )
|
|
\ . " " . s:key_bits . " >/dev/null 2>&1; echo $?" )
|
|
if s:genrsa
|
|
echoerr "Key generation failed!"
|
|
finish
|
|
endif
|
|
endif
|
|
|
|
" Set global configuration variable and define actual signature functions
|
|
let g:vim_keys = s:keys_dir
|
|
|
|
function! SignFile(filename,sigfile)
|
|
if !empty( glob( a:sigfile ) )
|
|
if delete( a:sigfile )
|
|
echoerr "Could not delete old signature file"
|
|
\ a:sigfile
|
|
return 0
|
|
endif
|
|
endif
|
|
|
|
" Load the file
|
|
if !filereadable( a:filename )
|
|
echoerr "File" a:filename "is not readable"
|
|
return 0
|
|
endif
|
|
try
|
|
let file_contents = readfile( a:filename , "b" )
|
|
catch /.*/
|
|
echoerr "Could not load" a:filename
|
|
return 0
|
|
endtry
|
|
|
|
" Compute checksum
|
|
let checksum = sha256( join( l:file_contents , "\n" ) )
|
|
|
|
" Sign and store checksum
|
|
let command = "echo " . l:checksum
|
|
\ . " | openssl rsautl -sign -inkey "
|
|
\ . shellescape( g:vim_keys . "/vim.key" )
|
|
\ . " -out " . shellescape( a:sigfile )
|
|
\ . " >/dev/null 2>&1; echo $?"
|
|
let rv = system( l:command )
|
|
if l:rv
|
|
echoerr "Signature failed for" a:filename
|
|
echoerr "Command was:" l:command
|
|
endif
|
|
return !l:rv
|
|
endfunction
|
|
|
|
function! CheckSignature(filename,sigfile)
|
|
let signed_sum = system( "openssl rsautl -verify -inkey "
|
|
\ . shellescape( g:vim_keys . "/vim.key" )
|
|
\ . " -in " . shellescape( a:sigfile )
|
|
\ . " 2>/dev/null" )
|
|
if signed_sum == ""
|
|
echoerr "Signature verification failed for" a:filename
|
|
return 0
|
|
endif
|
|
|
|
" Load the file
|
|
try
|
|
let file_contents = readfile( a:filename , "b" )
|
|
catch /.*/
|
|
echoerr "Could not load" a:filename
|
|
return 0
|
|
endtry
|
|
|
|
" Verify checksum
|
|
let computed = sha256( join( l:file_contents , "\n" ) )
|
|
if len( l:signed_sum ) > len( l:computed )
|
|
let l:signed_sum = l:signed_sum[ 0 : len( l:computed ) - 1 ]
|
|
endif
|
|
if l:computed != l:signed_sum
|
|
echoerr "Checksum mismatch for" a:filename
|
|
return 0
|
|
endif
|
|
return 1
|
|
endfunction
|