Added signature support (based on OpenSSL)
This commit is contained in:
parent
f3505375bf
commit
30eb46849b
1 changed files with 128 additions and 0 deletions
128
config-bits/01-signatures.vim
Normal file
128
config-bits/01-signatures.vim
Normal file
|
@ -0,0 +1,128 @@
|
|||
" 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
|
Loading…
Reference in a new issue