TOC |
|
Tcl GPGME provides a Tcl interface to the GnuGPG Made Easy library.
TOC |
TOC |
package provide gpgme 1.0
Tcl GPGME provides a Tcl interface to the GnuPG Made Easy library.
This document won't tell you what GPG[1] is. What it will tell you, the Tcl programmer, is how you can access the GPGME library from your Tcl script.
First, you'll need to have GPGME v0.3.11 (or later) already installed. Look in the download area.
GPGME requires GPG v1.0.7 (or later).
Look in the
download area.
Note that if you're upgrading to v1.0.7, then there's a disasterous little gotcha that will prevent programs like "Gabber" from working with GPG. Here's the diff you want to apply before compiling:
--- gnupg-1.0.7/g10/_g10.c Thu Apr 25 00:57:21 2002 +++ gnupg-1.0.7/g10/g10.c Wed Aug 28 13:12:49 2002 @@ -860,7 +860,9 @@ opt.homedir = buf; } #endif +#if 0 #undef USE_SHM_COPROCESSING /* huh? */ +#endif #ifdef USE_SHM_COPROCESSING if( opt.shm_coprocess ) { init_shm_coprocessing(requested_shm_size, 1 );
(Note that patch has no impact on GPGME, so if you want to use Tcl GPGME, but you're uncomfortable recompiling GPG, you don't need to install this patch.)
Finally, if for some reason you have this documentation, but not the source distribution of Tcl GPGME, you can find it here.
Although GPGME is described as "alpha" code and has an embyronic version number, it's surprisingly well-featured and stable.
Tcl GPGME implements most of GPGME with two exceptions:
As soon as I have a need for them, I'll implement them. Of course, this is all open source, so what's stopping you from doing the work?
TOC |
If an exception occurs in a GPGME library function, an error is thrown and the errorCode global is set to a list containing four elements:
A serialized array is a list that contains an series of keywords and values.
A serialized array can be traversed using foreach, e.g.,
foreach {k v} $aList { puts stdout "$k has value $v" }
Alternatively, an array can be initialized and accessed, e.g.,
array set data $aList if {[info exists data(plugin)]} { puts stdout "plugin entry is present" }
When Tcl GPGME returns a serialized array, a few properties, if present, are worth noting:
- key:
- contains a key token.
- signatures:
- contains a list of serialized arrays, each corresponding to a signature; in turn, each signature is a serialized array of properties.
- subkeys:
- contains a list of serialized arrays, one for each subkey present in a key.
- xml:
- a string containing an XML document describing a key or signature.
Callbacks are invoked with a single argument, a serialized array.
The passphrase callback returns a string. The serialized array contains these elements:
- token:
- a context token
- description:
- a string containing three lines:
- the string "ENTER" or "TRY_AGAIN";
- a userid "hint", consisting of the keyid for the (sub)key of interest, a space, and then the userid; and,
- passphrase information, consisting of four space-separated tokens: the keyid of the (sub)key of interest, the keyid of the corresponding mainkey, the algorithm number (e.g., DSA is 17), and the number 0.
(In case you're wondering, this format isn't part of the documented PGPME interface they'd be passed as individual elements in the serialized array.)
TOC |
gpgme::new
Return a "context token". To destroy it, rename it to the empty string.
$token -operation cancel
Cancel any pending operation for the context, e.g., a passphrase retrieval.
$token -operation wait \ ?-blocking boolean?
Wait for any pending operation to complete, optionally blocking. (Note that since the current version of Tcl GPGME doesn't support asynchronous operations, this is presently a no-op, as are the progress and idle callbacks.)
$token -operation get \ ?-property string?
Return a string corresponding to the value of the given -property. If no property is specified, a list of readable properties is returned.
$token -operation set \ ?-property string? \ ?-value string?
Set the -value of the given -property, and return the empty-string. If no property is specified, a list of writable properties is returned.
The syntax of some of these properties is worth mentioning:
- protocol:
- cf., gpgme::info protocols to see what choices are available
- armor/textmode:
- boolean
- keylistmode:
- a list of values, cf., gpgme::info keylist-modes to see what values are available
- passphrase-callback:
- a script, obviously
- signers:
- a list of key tokens
$token -operation info
Return a list of operations for the context token.
gpgme::recipient
Return a "recipients token". To destroy it, rename it to the empty string.
$token -operation add \ -name string \ ?-validity valid?
Add a name to the recipient set. The -validity switch indicates the minimum acceptable validity (cf., gpgme::info validity to see what choices are available).
$token -operation count
Return the number of names in the recipient set.
$token -operation list
Return a list of the names in the recipient set.
$token -operation info
Return a list of operations for the recipient token.
$token -operation start-key \ ?-pattern list? \ ?-secretonly boolean?
Start examining the context for keys that match any of the given patterns. Optionally, look for only those keys for which a secret key is available.
$token -operation next-key
Return a key token matching the given pattern.
$token -operation done-key
Cancel the search in progress.
$token -operation info-key
Return a serialized array of properties for the key token.
$token -operation start-trustitem \ -pattern string \ ?-maxlevel integer?
Start examining the context for trust items that match the given pattern.
$token -operation next-trustitem
Return an item token matching the given pattern.
$token -operation done-trustitem
Cancel the search in progress.
$token -operation info-trustitem
Return a serialized array of properties for the item token.
$token -operation encrypt \ -input string \ -recipients token \ ?-sign boolean?
Encipher the given string for the indicated recipients, optionally signing it, and return a binary string containing the result.
$token -operation decrypt \ -input string \ ?-checkstatus boolean?
Decipher the given string, optionally checking its signature validity, and return a serialized array. At a minimum, the serialized array has a plaintext property containing a binary string; it may also have a status property, describing the validity of the signature (cf., gpgme::info signature-status).
$token -operation sign \ -input string \ ?-mode mode?
Return a signature for the given string, (cf., gpgme::info signature-modes for the possible signature modes).
$token -operation verify -signature string \ ?-input string?
Check a signature's validity and return a serialized array. (If an input string is not present, then the signature's mode is either normal or cleartext; otherwise the mode is detached.) At a minimum, the serialized array has a status property describing the validity of the signature (cf., gpgme::info signature-status), and a signatures property; it may also have a plaintext property containing a binary string.
gpgme::check_version string
Verify that the GPGME library is at least as current as the indicated version, raise an error if not.
gpgme::get_engine_info
Return an XML document describing the configuration of the current protocol engine.
gpgme::engine_check_version protocol
Verify that the indicated protocol engine is propertly configured, raise an error if not.
TOC |
package require gpgme # get a passphrase from the user proc passphrase {data} { global passphrases array set params $data # break down the three lines... set lines [split [string trimright $params(description)] "\n"] set text [lindex $lines 0] if {[set x [string first " " [set keyid [lindex $lines 1]]]] > 0} { set userid [string range $keyid [expr $x+1] end] set keyid [string range $keyid 0 [expr $x-1]] } else { set userid unknown! } # see if we can use a cached value... if {([cequal $text ENTER]) \ &&([info exists passphrases($keyid)]) \ && (![cequal $passphrases($keyid) ""])} { return $passphrases($keyid) } set title "Please enter passphrase" switch -- $text { ENTER { } TRY_AGAIN { set title "Please try again" } default { append title ": " $text } } # prompt the user with $title, $keyid, $userid # ... if {!$abort} { return $passphrases($keyid) } $params(token) -operation cancel } # print info about a key proc printkey {ctx key} { foreach {k v} [$ctx -operation info-key \ -key $key] { switch -- $k { subkeys { set i 0 foreach subkey $v { puts stdout "subkey #[incr i]" foreach {k v} $subkey { puts stdout [format " %12.12s: %s" $k $v] } } } default { puts stdout [format " %12.12s: %s" $k $v] } } } } # 1. create a context for doing crypto set ctx [gpgme::context] $ctx -operation set \ -property passphrase-callback \ -value [list [namespace current]::passphrase] # 2. if we have multiple keys to sign with, let the user pick which # ones to use set keys {} $ctx -operation start-key \ -secretonly true while {[string compare [set key [$ctx -operation next-key]] ""]} { lappend keys $key } $ctx -operation done-key switch -- [llength $keys] { 0 { # well, ignore this... they'll get an error later on } 1 { # okay to proceed... } default { # present keys to user, reduce to a subset and then: $ctx -operation set \ -property signers \ -value $keys } } # 3. let's make a detached signature set input "..." set signature [$ctx -operation sign \ -input $input \ -mode detach] # 4. let's verify a detached signature puts stdout "operation: verify" foreach {k v} [$ctx -operation verify \ -input $input \ -signature $signature] { switch -- $k { signatures { foreach signature $v { puts stdout "\ninfo on signature" foreach {k v} $signature { switch -- $k { key { printkey $ctx $v } default { puts stdout [format " %12.12s: %s" $k $v] } } } } puts stdout "" } default { puts stdout [format " %12.12s: %s" $k $v] } } } # 5. let's encipher something set name fred@example.com set rset [gpgme::recipient] $rset -operation add \ -name $name \ -validity full # could add more, if we wanted... set ciphertext [$ctx -operation encrypt \ -input $input \ -recipients $rset] # 6. let's decipher it foreach {k v} [$ctx -operation decrypt \ -input $ciphertext \ -checkstatus yes] { puts stdout [format " %12.12s: %s" $k $v] }
TOC |
[1] | Callas, J., Donnerhacke, L., Finney, H. and R. Thayer, "OpenPGP Message Format", RFC 2440, November 1998 (TXT, HTML, XML). |
TOC |
Marshall T. Rose | |
Dover Beach Consulting, Inc. | |
POB 255268 | |
Sacramento, CA 95865-5268 | |
US | |
Phone: | +1 916 483 8878 |
Fax: | +1 916 483 8848 |
EMail: | mrose@dbc.mtview.ca.us |
TOC |
TOC |
(c) 2002 Marshall T. Rose
Hold harmless the author, and any lawful use is allowed.
TOC |