{************************************************************************}
{ }
{ Borland Delphi Runtime Library }
{ PGPsdk/pgpTLS interface unit }
{ }
{ Portions created by PGP/NAI are }
{ Copyright (C) 1997 Network Associates Inc. and affiliated companies. }
{ All Rights Reserved. }
{ }
{ The original file is: pgpGroups.h, released 10 Mar 1999. }
{ The original Pascal code is: pgpGroups.pas, released 10 May 2000. }
{ The initial developer of the Pascal code is Steven R. Heller }
{ <srheller@oz.net> }
{ }
{ Portions created by Steven R. Heller are }
{ Copyright (C) 2000 Steven R. Heller }
{ }
{ Contributors: }
{ The ASM technique for accessing open arrays is based on the }
{ original work of Graham Grieve in Kestral Computing's }
{ PGPAPI.PAS file: <http://www.kestral.com.au/devtools/pgp> }
{ }
{ You may retrieve the latest version of this file here: }
{ <http://www.oz.net/~srheller/pgpsdk> }
{ }
{ Please see }
{ <http://www.oz.net/~srheller/pgpsdk/index.html#groups> for }
{ information on using this unit. }
{ }
{ The contents of this file are used with permission, subject to }
{ the Mozilla Public License Version 1.1 (the "License"); you may }
{ not use this file except in compliance with the License. You may }
{ obtain a copy of the License at }
{ <http://www.mozilla.org/MPL/MPL-1.1.html> }
{ }
{ Software distributed under the License is distributed on an }
{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
{ implied. See the License for the specific language governing }
{ rights and limitations under the License. }
{ }
{************************************************************************}
unit pgpGroups;
interface
uses
pgpBase, pgpPubTypes;
const
kPGPMaxGroupNameLength = 63;
kPGPMaxGroupDescriptionLength = 63;
type
PGPGroupName = array[0..kPGPMaxGroupNameLength] of char;
PGPGroupDescription = array[0..kPGPMaxGroupDescriptionLength] of char;
pPGPGroupSet = pointer;
pPGPGroupItemIter = pointer;
// any type will do that is distinct
PGPGroupID = PGPUInt32;
type
PGPGroupItemType = PGPEnumType;
const
kPGPGroupItem_KeyID = 1;
kPGPGroupItem_Group = 2;
{____________________________________________________________________________
A run-time group item, used when iterating through a group.
For client use; not necessarily the internal storage format.
'userValue' is *not* saved to disk.
____________________________________________________________________________}
(*
typedef struct PGPGroupItem
{
PGPGroupItemType type;
PGPUserValue userValue;
union
{
{ type selects which substructure }
struct { if kGroupItem_Group }
{
PGPGroupID id;
} group;
struct { if kGroupItem_KeyID }
{
PGPPublicKeyAlgorithm algorithm;
PGPKeyID keyID;
} key;
} u;
PGPUInt32 reserved[4];
} PGPGroupItem;
*)
// substructures for TPGPGroupItem union, added by SRH
type
TSubstructGroup = packed record
Id: PGPGroupID;
end;
type
TSubstructKey = packed record
Algorithm: PGPPublicKeyAlgorithm;
KeyID: TPGPKeyID;
end;
type
pPGPGroupItem = ^TPGPGroupItem;
TPGPGroupItem = packed record
aType: PGPGroupItemType;
UserValue: PGPUserValue;
u:
record
{ type selects which substructure }
case Integer of
1 : { if kGroupItem_Group }
(Group: TSubstructGroup;);
2 : { if kGroupItem_KeyID }
(Key: TSubstructKey;);
end;// case
reserved: array[0..3] of PGPUInt32;
end;
// oh, how I love unions
type
TPGPGroupItemCompareProc = function(var Group1: pPGPGroupItem;
Group2: pPGPGroupItem; UserValue: PGPUserValue): PGPInt32 cdecl;
{____________________________________________________________________________
Info obtained via PGPGetGroupInfo.
____________________________________________________________________________}
type
TPGPGroupInfo = record
Id : PGPGroupID;
Name : PGPGroupName;
Description : PGPGroupName;
UserValue : PGPUserValue;
end;
type
TPGPGroupItemIterFlags = PGPFlags;
const
// flag (1 shl 0 ) is reserved
kPGPGroupIterFlags_Recursive = (1 shl 1);// (1UL << 1 )
kPGPGroupIterFlags_Keys = (1 shl 2);// (1UL << 2 )
kPGPGroupIterFlags_Groups = (1 shl 3);// (1UL << 3 )
kPGPGroupIterFlags_AllKeysRecursive = kPGPGroupIterFlags_Recursive or kPGPGroupIterFlags_Keys;
kPGPGroupIterFlags_AllGroupsRecursive = kPGPGroupIterFlags_Recursive or kPGPGroupIterFlags_Groups;
kPGPGroupIterFlags_AllItems = kPGPGroupIterFlags_Keys or kPGPGroupIterFlags_Groups;
kPGPGroupIterFlags_AllRecursive = kPGPGroupIterFlags_Recursive or kPGPGroupIterFlags_AllItems;
{____________________________________________________________________________
Manipulating pgp group sets (pPGPGroupSet)
____________________________________________________________________________}
{ create a new, empty groups collection }
var PGPNewGroupSet: function(Context: pPGPContext;
var OutRef: pPGPGroupSet): PGPError cdecl;
{ file is *not* left open; all data is loaded into memory }
var PGPNewGroupSetFromFile: function(Context: pPGPContext;
aFile: pPGPFileSpec;
var OutRef: pPGPGroupSet): PGPError cdecl;
{ overwrites existing. Don't bother unless PGPGroupSetNeedsCommit() }
var PGPSaveGroupSetToFile: function(TheSet: pPGPGroupSet; aFile: pPGPFileSpec): PGPError cdecl;
{ free all data structures; be sure to save first if you want }
var PGPFreeGroupSet: function(TheSet: pPGPGroupSet): PGPError cdecl;
{ has the group changed? }
var PGPGroupSetNeedsCommit: function(TheSet: pPGPGroupSet): PGPBoolean cdecl;
var PGPGetGroupSetContext: function(TheSet: pPGPGroupSet): pPGPContext cdecl;
{ export the groupset to a buffer. Use PGPFreeData to free the buffer }
var PGPExportGroupSetToBuffer: function(TheSet: pPGPGroupSet;
var Buffer: pointer;
var BufferSize: PGPSize): PGPError cdecl;
{ import a groupset from a buffer }
var PGPImportGroupSetFromBuffer: function(Context: pPGPContext;
var Buffer: pointer;
BufSize: PGPSize;
var OutSet: pPGPGroupSet): PGPError cdecl;
{____________________________________________________________________________
Manipulating groups
Groups are always referred to by IDs which remain valid until the set
is disposed.
____________________________________________________________________________}
{ initial parent ID is kPGPInvalidGroupID }
var PGPNewGroup: function(TheSet: pPGPGroupSet;
const Name: PChar;
const Description: PChar;
var Id: PGPGroupID): PGPError cdecl;
var PGPCountGroupsInSet: function(TheSet: pPGPGroupSet;
var NumGroups: PGPUInt32): PGPError cdecl;
var PGPGetIndGroupID: function(TheSet: pPGPGroupSet;
GroupIndex: PGPUInt32;
var Id: PGPGroupID): PGPError cdecl;
{ delete this group from the Set: }
{ All references to it are removed in all sets }
var PGPDeleteGroup: function(TheSet: pPGPGroupSet;
Id: PGPGroupID): PGPError cdecl;
{ delete the indexed item from the group }
{ the item may be a group or a key }
var PGPDeleteIndItemFromGroup: function(TheSet: pPGPGroupSet;
Id: PGPGroupID;
Item: PGPUInt32): PGPError cdecl;
{ same as PGPDeleteIndItemFromGroup, but accepts an item }
var PGPDeleteItemFromGroup: function(TheSet: pPGPGroupSet;
Id: PGPGroupID;
const Item: pPGPGroupItem): PGPError cdecl;
var PGPGetGroupInfo: function(TheSet: pPGPGroupSet;
Id: PGPGroupID;
var Info: TPGPGroupInfo): PGPError cdecl;
var PGPSetGroupName: function(TheSet: pPGPGroupSet;
Id: PGPGroupID;
const Name: PChar): PGPError cdecl;
var PGPSetGroupUserValue: function(TheSet: pPGPGroupSet;
Id: PGPGroupID;
UserValue: PGPUserValue): PGPError cdecl;
var PGPSetGroupDescription: function(TheSet: pPGPGroupSet;
Id: PGPGroupID;
const Name: PChar): PGPError cdecl;
{ 'item' specifies a group or a key id }
{ you must fill the item in completely }
var PGPAddItemToGroup: function(TheSet: pPGPGroupSet;
const Item: pPGPGroupItem;
Group: PGPGroupID): PGPError cdecl;
var PGPMergeGroupIntoDifferentSet: function(FromSet: pPGPGroupSet;
FromId: PGPGroupID;
ToSet: pPGPGroupSet): PGPError cdecl;
var PGPMergeGroupSets: function(FromSet: pPGPGroupSet;
IntoSet: pPGPGroupSet): PGPError cdecl;
var PGPCopyGroupSet: function(SourceSet: pPGPGroupSet;
var DestSet: pPGPGroupSet): PGPError cdecl;
{____________________________________________________________________________
Manipulating group items
____________________________________________________________________________}
{ count how many items there are in a group }
{ totalItems includes keys and groups }
var PGPCountGroupItems: function(TheSet: pPGPGroupSet;
Id: PGPGroupID;
Recursive: PGPBoolean;
var NumKeys: PGPUInt32;
var TotalItems: PGPUInt32): PGPError cdecl;
{ non-recursive call; index only applies to group itself }
var PGPGetIndGroupItem: function(TheSet: pPGPGroupSet;
Id: PGPGroupID;
GroupIndex: PGPUInt32;
var Item: TPGPGroupItem): PGPError cdecl;
{ use PGPGetIndGroupItem() if you want to get the user value }
var PGPSetIndGroupItemUserValue: function(TheSet: pPGPGroupSet;
Id: PGPGroupID;
GroupIndex: PGPUInt32;
UserValue: PGPUserValue): PGPError cdecl;
var PGPSortGroupItems: function(TheSet: pPGPGroupSet;
Id: PGPGroupID;
CompareProc: TPGPGroupItemCompareProc;// ?? T or p?
UserValue: PGPUserValue): PGPError cdecl;
var PGPSortGroupSet: function(TheSet: pPGPGroupSet;
CompareProc: TPGPGroupItemCompareProc;// ?? T or p?
UserValue: PGPUserValue): PGPError cdecl;
{____________________________________________________________________________
PGPGroupItemIterRef--iterator through group items.
Special note: this is not a full-fledged iterator. You may *not* add
or delete items while iterating and you may only move forward. However,
you may change the values of items.
____________________________________________________________________________}
var PGPNewGroupItemIter: function(TheSet: pPGPGroupSet;
Id: PGPGroupID;
Flags: TPGPGroupItemIterFlags;
var Iter: pPGPGroupItemIter): PGPError cdecl;
var PGPFreeGroupItemIter: function(Iter: pPGPGroupItemIter): PGPError cdecl;
{ returns kPGPError_EndOfIteration when done }
var PGPGroupItemIterNext: function(Iter: pPGPGroupItemIter;
var Item: TPGPGroupItem): PGPError cdecl;
{____________________________________________________________________________
Group utilities
____________________________________________________________________________}
{____________________________________________________________________________
Return the lowest validity of any item in the group
keyset should contain all keys available
It is not an error if keys can't be found; you may want to check
the not found count.
The lowest validity is kPGPValidity_Invalid and kPGPValidity_Unknown
is never returned.
____________________________________________________________________________}
var PGPGetGroupLowestValidity: function(TheSet: pPGPGroupSet;
Id: PGPGroupID;
KeySet: pPGPKeySet;
var LowestValidity: PGPValidity;
var NumKeysNotFound: PGPUInt32): PGPError cdecl;
{____________________________________________________________________________
All all the keys in the group (and its subgroups) to the keyset
____________________________________________________________________________}
var PGPNewKeySetFromGroup: function(TheSet: pPGPGroupSet;
Id: PGPGroupID;
MasterSet: pPGPKeySet;
var ResultSet: pPGPKeySet;
var NumKeysNotFound: PGPUInt32): PGPError cdecl;
{____________________________________________________________________________
Create a simple, flattened group of unique key IDs from the source group.
Note that sourceSet and destSet must be different.
____________________________________________________________________________}
var PGPNewFlattenedGroupFromGroup: function(SourceSet: pPGPGroupSet;
SourceId: PGPGroupID;
DestSet: pPGPGroupSet;
var DestID: PGPGroupID): PGPError cdecl;
{____________________________________________________________________________
Perform a "standard" sort on a group
____________________________________________________________________________}
var PGPSortGroupSetStd: function(TheSet: pPGPGroupSet;
Keys: pPGPKeySet): PGPError cdecl;
{did this unit load the DLL successfully?}
//var pgpGroupsLoaded: Boolean = False;
function LoadpgpGroups: Boolean; //returns True if API successfully loaded
procedure UnLoadpgpGroups;
function pgpGroupsLoaded: Boolean; //returns if the API is loaded
implementation
uses
Windows;
var
PGPsdkLib: HModule;
function pgpGroupsLoaded: boolean;
begin
result := PGPsdkLib >= 32;
end;
function LoadpgpGroups: boolean;
begin
// groups aren't in pgp 5, try to load pgp 6 only
PGPsdkLib := LoadLibrary('pgp_sdk.dll');
if pgpGroupsLoaded then
begin
result := True;
@PGPNewGroupSet := GetProcAddress(PGPsdkLib,'PGPNewGroupSet');
@PGPNewGroupSetFromFile := GetProcAddress(PGPsdkLib,'PGPNewGroupSetFromFile');
@PGPSaveGroupSetToFile := GetProcAddress(PGPsdkLib,'PGPSaveGroupSetToFile');
@PGPFreeGroupSet := GetProcAddress(PGPsdkLib,'PGPFreeGroupSet');
@PGPGroupSetNeedsCommit := GetProcAddress(PGPsdkLib,'PGPGroupSetNeedsCommit');
@PGPGetGroupSetContext := GetProcAddress(PGPsdkLib,'PGPGetGroupSetContext');
@PGPExportGroupSetToBuffer := GetProcAddress(PGPsdkLib,'PGPExportGroupSetToBuffer');
@PGPImportGroupSetFromBuffer := GetProcAddress(PGPsdkLib,'PGPImportGroupSetFromBuffer');
@PGPNewGroup := GetProcAddress(PGPsdkLib,'PGPNewGroup');
@PGPCountGroupsInSet := GetProcAddress(PGPsdkLib,'PGPCountGroupsInSet');
@PGPGetIndGroupID := GetProcAddress(PGPsdkLib,'PGPGetIndGroupID');
@PGPDeleteGroup := GetProcAddress(PGPsdkLib,'PGPDeleteGroup');
@PGPDeleteIndItemFromGroup := GetProcAddress(PGPsdkLib,'PGPDeleteIndItemFromGroup');
@PGPDeleteItemFromGroup := GetProcAddress(PGPsdkLib,'PGPDeleteItemFromGroup');
@PGPGetGroupInfo := GetProcAddress(PGPsdkLib,'PGPGetGroupInfo');
@PGPSetGroupName := GetProcAddress(PGPsdkLib,'PGPSetGroupName');
@PGPSetGroupUserValue := GetProcAddress(PGPsdkLib,'PGPSetGroupUserValue');
@PGPSetGroupDescription := GetProcAddress(PGPsdkLib,'PGPSetGroupDescription');
@PGPAddItemToGroup := GetProcAddress(PGPsdkLib,'PGPAddItemToGroup');
@PGPMergeGroupIntoDifferentSet := GetProcAddress(PGPsdkLib,'PGPMergeGroupIntoDifferentSet');
@PGPMergeGroupSets := GetProcAddress(PGPsdkLib,'PGPMergeGroupSets');
@PGPCopyGroupSet := GetProcAddress(PGPsdkLib,'PGPCopyGroupSet');
@PGPCountGroupItems := GetProcAddress(PGPsdkLib,'PGPCountGroupItems');
@PGPGetIndGroupItem := GetProcAddress(PGPsdkLib,'PGPGetIndGroupItem');
@PGPSetIndGroupItemUserValue := GetProcAddress(PGPsdkLib,'PGPSetIndGroupItemUserValue');
@PGPSortGroupItems := GetProcAddress(PGPsdkLib,'PGPSortGroupItems');
@PGPSortGroupSet := GetProcAddress(PGPsdkLib,'PGPSortGroupSet');
@PGPNewGroupItemIter := GetProcAddress(PGPsdkLib,'PGPNewGroupItemIter');
@PGPFreeGroupItemIter := GetProcAddress(PGPsdkLib,'PGPFreeGroupItemIter');
@PGPGroupItemIterNext := GetProcAddress(PGPsdkLib,'PGPGroupItemIterNext');
@PGPGetGroupLowestValidity := GetProcAddress(PGPsdkLib,'PGPGetGroupLowestValidity');
@PGPNewKeySetFromGroup := GetProcAddress(PGPsdkLib,'PGPNewKeySetFromGroup');
@PGPNewFlattenedGroupFromGroup := GetProcAddress(PGPsdkLib,'PGPNewFlattenedGroupFromGroup');
@PGPSortGroupSetStd := GetProcAddress(PGPsdkLib,'PGPSortGroupSetStd');
end
else
result := false;
end;
procedure UnLoadpgpGroups;
begin
if pgpGroupsLoaded then
begin
if PGPsdkLib <> 0 then
FreeLibrary(PGPsdkLib);
PGPsdkLib := 0;
end;
end;
initialization
LoadpgpGroups;
finalization
if pgpGroupsLoaded then
UnloadpgpGroups;
end.