1. Status
Status of the signature; a number corresponding to one of the following constants:
SIGNED_GOOD = 0 (good signature)
SIGNED_NOT = 1 (no signature)
SIGNED_BAD = 2 (bad signature)
SIGNED_NO_KEY = 3 (signature present, but made with a key not on the keyring -- remember that SPGP uses the default keyring, only)
If the first element of the string is "1" there will be no other elements.
2. User ID
Primary user-ID of the signing key. (E.g., "Test Key <test@test.key>")
3. Key ID
ID number of the signing key. (E.g., "0xD71F6FE5")
4. Date and Time (string)
The signature's date and time, in C/UNIX "ctime" format, adjusted to local time. (E.g., "Thu Oct 01 20:42:41 1998")
5. Date and Time (seconds)
The signature's date and time, in C/UNIX "ctime" seconds (i.e., the number of seconds since 1 January 1970). This is included so that you may convert and format the date & time to your own specifications. Note that this date & time will be GMT/UTC, not local time. (E.g., "907299761").
6. Signature Checked
A boolean value (1 or 0) indicating whether the signing key is available and the message is formatted properly. If this value and (7), below, are both True, the signature is valid.
7. Signature Verified
A boolean value (1 or 0) indicating whether the signed data is unchanged. Both (6) and (7) must be true for the signature to be valid.
8. Key Validity
The signing key's current level of validity; a number corresponding to one of the following constants:
PGPValidity_Unknown = 0
PGPValidity_Invalid = 1
PGPValidity_Marginal = 2
PGPValidity_Complete = 3
9. Key Revoked
A boolean value (1 or 0) indicating whether the signing key is revoked.
10. Key Disabled
A boolean value (1 or 0) indicating whether the signing key is disabled.
11. Key Expired
A boolean value (1 or 0) indicating whether the signing key has expired.
Notes and warnings:
Starting with SPGP 2.5, a new system of returning key properties is available. Eventually (version 3.0) the old system will be completely replaced. Until then, only certain functions introduced in 2.5 use this new system.
The new system uses two parameters: a string buffer to receive the key-properties string, and a long integer (usually named 'Flags') containing bit-flags indicating which properties to return. The developer choses the desired properties and sets the bits by combining the appropriate constants in a 'bitwise OR' operation. The function returns the properties as a tab-delimited string ending in a CR-LF. For example, if the desired properties were hex ID, primary user ID, and creation date, the flags would be set like this:
Flags = spgpKeyProp_KeyID Or spgpKeyProp_UserID Or spgpKeyProp_CreationTimeStr... and the function would return something like this:
0xD71F6FE5 Test Key <test@test.key> Thu Sep 24 21:43:47 1998
This new system puts much more control in the hands of the developer. Unlike the existing system, it is also flexible. New properties can be added without messing up existing code, because only the available constants need to change, not the format of the string itself. The chief disadvantage is only temporary: the new-style strings will not have their properties in the same positions as the old strings, so existing code will have to be adjusted. See the Notes below for more on the order of the properties in new-style strings.
The available properties are listed in the table below. They are divided into string, numeric, and boolean properties for convenience only. They will of course all be returned as part of a string. The maximum size (in characters) is given so that the developer can anticipate the maximum size of a requested string. Note that the size will increase by 1 for the TAB character following each property and by an additional 2 for the CR-LF at the end of the string.
Constant | Max. Size | Description |
---|---|---|
string properties | ||
spgpKeyProp_KeyIdShort | 10 | Abbreviated Key ID, in hex, including the '0x' prefix. This is the 8-character ID most people are familiar with. |
spgpKeyProp_KeyIdLong | 18 | Full Key ID, in hex, including the '0x' prefix. |
spgpKeyProp_KeyID | 10 | Alias for spgpKeyProp_KeyIdShort. |
spgpKeyProp_UserID | 256 | Primary user ID. This is by convention a name and an e-mail address |
spgpKeyProp_Fingerprint | 20 | Fingerprint, in hex. RSA key fingerprints have 16 characters; DSA keys have 20. |
spgpKeyProp_CreationTimeStr | 24 | Creation date and time as a string, converted to local time. |
spgpKeyProp_ExpirationTimeStr | 24 | Expiration date and time as a string, converted to local time. Not all keys have an expiration date and time. |
numeric properties | ||
spgpKeyProp_Keybits | 11 | Size of the key, in bits. If a sub-key is present, its size will be listed first (e.g., "2048/1024"), so it is important to test this value before converting it to an integer. |
spgpKeyProp_KeyAlg | 2 | The key's public-key algorithm; a value corresponding to one of the following constants: PGPKeyAlgorithm_RSA PGPKeyAlgorithm_RSAEncryptOnly PGPKeyAlgorithm_RSASignOnly PGPKeyAlgorithm_ElGamal PGPKeyAlgorithm_DSA |
spgpKeyProp_Trust | 2 | The trust level you have assigned to the key or which it has by virtue of being your own private key; a value corresponding to one of the following constants: PGPKeyTrust_Undefined PGPKeyTrust_Unknown PGPKeyTrust_Never PGPKeyTrust_Marginal PGPKeyTrust_Complete PGPKeyTrust_Ultimate |
spgpKeyProp_Validity | 2 | The signing key's current level of validity; a value corresponding to one of the following constants: PGPValidity_Unknown PGPValidity_Invalid PGPValidity_Marginal PGPValidity_Complete |
spgpKeyProp_CreationTime | 9 | Creation date and time, in C/UNIX "ctime" seconds (i.e., the number of seconds since 1 January 1970). This will be GMT, not local time. |
spgpKeyProp_ExpirationTime | 9 | Expiration date and time, in C/UNIX "ctime" seconds (i.e., the number of seconds since 1 January 1970). Not all keys have an expiration date and time. |
boolean properties | ||
spgpKeyProp_IsSecret | 1 | Is a secret key present? |
spgpKeyProp_IsAxiomatic | 1 | Is the key axiomatically trusted ("implicit trust")? |
spgpKeyProp_IsRevoked | 1 | Is the key revoked? |
spgpKeyProp_IsDisabled | 1 | Is the key disabled? |
spgpKeyProp_IsExpired | 1 | Is the key expired? |
spgpKeyProp_IsSecretShared | 1 | Is the key split into shares? (PGP 6+ only) |
spgpKeyProp_CanEncrypt | 1 | Can the key encrypt? |
spgpKeyProp_CanDecrypt | 1 | Can the key decrypt? (PGP 6+ only) |
spgpKeyProp_CanSign | 1 | Can the key sign? |
spgpKeyProp_CanVerify | 1 | Can the key verify a signature? (PGP 6+ only) |
spgpKeyProp_HasRevoker | 1 | Does the key have 1 or more designated revokers? (DSA keys only.) |
spgpKeyProp_HasADK | 1 | Does the key have 1 or more Additional Decryption Keys? (DSA keys only.) |
spgpKeyProp_HasSubKey | 1 | Does the key have 1 or more sub-keys? (DSA keys only.) |
Notes
spgpKeyProp_HasSubKey Or spgpKeyProp_IsDisabled Or spgpKeyProp_HasRevoker
, but the properties-string will list them in this order: IsDisabled, HasRevoker, HasSubKey. The developer cannot determine the order of the properties.
1. Key Type
A boolean value (1 or 0) indicating whether or not a private key is present.
2. Key ID
ID number of the key. (E.g., "0xD71F6FE5")
3. User ID
Primary user-ID of the key. (E.g., "Test Key <test@test.key>")
4. Key Size
The size of the key, in bits. If a DSA key has an attached sub-key, the sub-key's size will be listed first. (E.g., "1024" For an RSA or DSA key, "2048/1024" for an ElGamal/DSA key)
5. Date and Time (string)
The key's creation date and time, in C/UNIX "ctime" format, adjusted to local time. (E.g., "Thu Oct 01 20:42:41 1998")
6. Date and Time (seconds)
The key's creation date and time, in C/UNIX "ctime" seconds (i.e., the number of seconds since 1 January 1970). This is included so that you may convert and format the date & time to your own specifications. Note that this date & time will be GMT/UTC, not local time. (E.g., "907299761").
7. Fingerprint
The key's "fingerprint", in hexadecimal characters. (E.g., "1FB67C09D5319ED947520A225A926150")
8. Trust
The trust level you have assigned to the key or which it has by virtue of being your own private key; a number corresponding to one of the following constants:
PGPKeyTrust_Undefined = 0
PGPKeyTrust_Unknown = 1
PGPKeyTrust_Never = 2
PGPKeyTrust_Marginal = 5
PGPKeyTrust_Complete = 6
PGPKeyTrust_Ultimate = 7
9. Validity
The key's current level of validity; a number corresponding to one of the following constants:
PGPKeyValidity_Unknown = 0
PGPKeyValidity_Invalid = 1
PGPKeyValidity_Marginal = 2
PGPKeyValidity_Complete = 3
10. Key Algorithm
The key's public-key algorithm; a number corresponding to one of the following constants:
PGPKeyAlgorithm_RSA = 1
PGPKeyAlgorithm_RSAEncryptOnly = 2
PGPKeyAlgorithm_RSASignOnly = 3
PGPKeyAlgorithm_ElGamal = 4
PGPKeyAlgorithm_DSA = 5
Notes and warnings:
-----BEGIN PGP...
" lines, is called by PGP a "lexical section". The developer my expect most SPGP functions to work only with the first Lexical Section found in a text buffer or file. The major exception to this rule is decryption: if multiple sections are input, any sections for which appropriate keys/passphrases are available will be decrypted and their plaintext combined in the resulting output. The safest course is to assume nothing and only input one lexical section at a time.
First, there is a simple, practical reason: Hex IDs are almost unique, but E-Mail IDs are not -- and in the age of widespread use of both RSA and DH/DSS keys, you are safer in assuming that some E-Mail IDs will be duplicated on any given key-ring. If you are using one of the functions which take a single Key ID as a parameter -- spgpKeyDisable, for example -- and there are two keys with the same E-Mail ID (one RSA, one DH/DSS), you will not be able to disable the RSA key because of the way PGP sorts keys, which is DH/DSS-first. The function will only be able to find the first single key matching the E-Mail ID, not the second. The moral is that even when you are not encrypting, it is important to be specific about which key you are using, and the best way to do that is with a Hex ID.
Use of an E-mail ID also involves serious potential security risks.
Test this yourself: take the "test key" that comes with SPGP and add another name to the key, using the e-mail address from your own key. Now use the VB5 sample application to encrypt some text to your public key (using your e-mail address as an E-mail ID), and use PGP's client to decrypt the output. You'll see "<test@test.key>" on the recipients list. Now, think of how a Bad Guy could use this to compromise your user's security. (If you can't think of a way, I've written a simple scenario to illustrate the point.)
How you can avoid this scenario? Use Hex IDs only. Start by extracting the primary User IDs from the local ring via spgpKeyRingID or spgpKeyRingToFile, extracting from those strings the E-mail ID and Hex ID for each key. Associate these in whatever way you prefer -- in a table, in a record, etc. Then, rather than asking the user for an e-mail address, show (a la PGPKeys) a list of available User IDs and let the user select recipients. (This also prevents "key not found" errors by limiting the choices to keys you know are on the local ring.) When the user selects a User ID, you use the associated Hex ID as the function parameter.
Show User IDs to the user, but give Hex IDs to SPGP. This way you can be user-friendly and safe at the same time.
Definitions:
Strictly speaking, the PGP version is irrelevant to SPGP; all that matters is the underlying SDK API version. However, "PGP 6.x required" is more comprehensible than "SDK API version 3.x required", because most users have no idea what API version their installed PGP version is using. (And why should they? APIs are for developers.) The more familiar "PGP version" is used throughout this reference, but what really matters is the underlying API version.
To translate between API and PGP versions, you can use the following schedule, which is adapted from a similar table in the PGP sources. Note that the API version is in hex, not the long integer returned by the spgpSdkApiVersion function, so it must be converted by the developer. (The PGPsdk includes three macros to split the hex-value into major, minor, and bugfix numbers via bit-shifting, but these have no application to SPGP.)
SDK API Version | Documented in | Used in |
---|---|---|
0x01000000 | SDK 1.0.0 | PGP 5.5 |
0x02000000 | SDK 1.1.0 | ? |
0x02000010 | SDK 1.1.1 | PGP 5.5.3 |
0x03000000 | SDK 1.5 | PGP 6.0 |
0x03000010 | SDK 1.5.1 | ? |
0x03000020 | SDK 1.5.2 | PGP 6.02 |
0x03001000 | SDK 1.6 | ? |
0x03002000 | SDK 1.7 | ? |
0x03002010 | SDK 1.7.1 | PGP 6.5.1, 6.5.2, 6.5.3 |
Example: The developer wants to use a feature which is only available in PGP 6.x, so the API version must be 0x3000000 or higher. spgpSdkApiVersion returns '50331680', which in hexadecimal is '0x3000020', so the feature should be available.