Thanks for the input. The code is a little convoluted, so I'll try to include only some of the major parts.
createGroup('ADMIN','foo');
createUser('USER1','bar');
createUser('USER2','bar2');
addGroupUser('USER1','ADMIN');
decryptGroupData('ADMIN','bar');
sub initPGP {
my($uid) = @_;
my(%args,$sql,$sth,$ret,$public,$secret,$ring,$kb,$pubring,$secrin
+g);
if ($uid =~ m#\d{3,6}$#) {
$sql = "SELECT public,secret
FROM gpg_user
WHERE code=$uid";
} else {
$sql = "SELECT public,secret
FROM gpg_group
WHERE group_name='$uid'";
}
$sth = runSQL($sql);
$ret = $sth->fetchrow_arrayref;
if ($ret) {
($public,$secret) = unarmourKeys($ret->[0],$ret->[1]);
$pubring = Crypt::OpenPGP::KeyRing->new( Data => $pub
+lic );
$secring = Crypt::OpenPGP::KeyRing->new( Data => $sec
+ret );
$kb = $pubring->find_keyblock_by_uid($uid);
$args{SecRing} = $secring;
$args{PubRing} = $pubring;
}
$args{Compat} = COMPAT;
$args{Verbosity} = DEBUG;
return(Crypt::OpenPGP->new(%args),$kb);
}
sub unarmourKeys {
my($public,$secret) = @_;
my($pubsaved,$secsaved);
$pubsaved = uri_unescape($public);
$secsaved = uri_unescape($secret);
$pubsaved = Crypt::OpenPGP::Armour->unarmour($pubsaved);
$secsaved = Crypt::OpenPGP::Armour->unarmour($secsaved);
return($pubsaved->{Data},$secsaved->{Data});
}
sub addGroupUser {
my($code,$grouppass,$group) = @_;
my($groupid,$sql);
$groupid = getGroupID($group);
if ($code && $groupid) {
$sql = "INSERT INTO gpg_group_user(groupid,code)
VALUES ('$groupid','$code')";
runSQL($sql);
encryptGroupData($grouppass,$group);
}
}
sub createUser {
my($code,$password) = @_;
my($info,$public,$secret,$finger,$keyid,$uid,
$sql,$data,$pubring,$secring,@recipients);
$info = genKeys($password,$code);
$public = $info->{public};
$secret = $info->{secret};
$finger = $info->{finger};
$keyid = $info->{keyid};
if ($finger) {
$sql = "INSERT INTO gpg_user(code,public,secret,fingerprint)
VALUES ($code,'$public','$secret','$finger')";
runSQL($sql);
push(@recipients, $keyid);
($pubring,$secring) = unarmourKeys($public,$secret);
print "ENCODED: " . encode_base64($password) . "\n";
$info->{public} = $pubring;
$info->{secret} = $secring;
$info->{text} = encode_base64($password);
$info->{recipients} = \@recipients;
$info->{password} = $password;
$data = encryptData($code,$info);
$sql = "UPDATE gpg_user SET data='$data' WHERE code='$code'";
runSQL($sql);
}
}
sub createGroup {
my($group, $password) = @_;
my($sql,$info,$pubring,$secring,@recipients,$public,$secret,$data);
$info = genKeys($password,$group);
if ($info->{keyid}) {
$public = $info->{public};
$secret = $info->{secret};
push(@recipients, $info->{keyid});
($pubring,$secring) = unarmourKeys($public,$secret);
$info->{public} = $pubring;
$info->{secret} = $secring;
$info->{text} = encode_base64($password);
$info->{recipients} = \@recipients;
$info->{password} = $password;
$data = encryptData($group,$info);
$sql = "INSERT INTO gpg_group(group_name,fingerprint,public,
secret,description,data)
VALUES ('$group','$info->{finger}','$public',
'$secret','','$data')";
runSQL($sql);
}
}
sub encryptData {
my($groups,$info) = @_;
my($pgp,$encrypt,$kb,%encArgs,$group);
$pgp = initRingsPGP($info->{public},$info->{secret});
$encArgs{Data} = $info->{text};
$encArgs{Recipients} = $info->{recipients};
$encArgs{Armour} = 1;
$encrypt = $pgp->encrypt(%encArgs) or die "Error encrypt: " . $pgp
+->errstr;
$encrypt = uri_escape($encrypt);
return($encrypt);
}
sub initRingsPGP {
my($public,$secret) = @_;
my($pubring,$secring,%args);
$pubring = Crypt::OpenPGP::KeyRing->new( Data => $public );
$secring = Crypt::OpenPGP::KeyRing->new( Data => $secret );
$args{SecRing} = $secring;
$args{PubRing} = $pubring;
$args{Compat} = COMPAT;
$args{Verbosity} = DEBUG;
return(Crypt::OpenPGP->new(%args));
}
sub encryptGroupData {
my($grouppass,$group) = @_;
my($text,$info,$encrypt,$sql);
$info = setGroupRecipients($group);
$info->{text} = encode_base64($grouppass);
$encrypt = encryptData($group,$info);
$sql = "UPDATE gpg_group SET data='$encrypt'
WHERE group_name='$group'";
runSQL($sql);
}
sub setGroupRecipients {
my($group) = @_;
my(@recipients,$info,$ring,$public,$uids);
$info = getGroupUsersPubkey($group);
$public = $info->{public};
$uids = $info->{uids};
$ring = Crypt::OpenPGP::KeyRing->new( Data => $public );
foreach my $uid (@{$uids}) {
my $kb = $ring->find_keyblock_by_uid($uid);
my $keyid = $kb->key->key_id_hex;
push(@recipients, $keyid);
}
push(@recipients, $info->{keyid} );
$info->{recipients} = \@recipients;
return($info);
}
sub getGroupUsersPubkey {
my($group) = @_;
my($sql,$sth,$ret,@public,@secret,@uids,$info,$ring,$kb,$keyid,@ke
+yids);
$sql = "SELECT public,secret FROM gpg_group WHERE group_name='$gro
+up'";
$sth = runSQL($sql);
$ret = $sth->fetchrow_arrayref;
my($pubring,$secring) = unarmourKeys($ret->[0],$ret->[1]);
push(@public, $pubring );
push(@secret, $secring );
$ring = Crypt::OpenPGP::KeyRing->new( Data => $pubring );
$kb = $ring->find_keyblock_by_uid($group);
$keyid = $kb->key->key_id_hex;
$sql = "SELECT u.code,u.public,u.secret
FROM gpg_user u, gpg_group_user i, gpg_group g
WHERE u.code=i.code AND i.groupid=g.id
AND g.group_name='$group'";
$sth = runSQL($sql);
while($ret = $sth->fetchrow_arrayref) {
my($pub,$sec) = unarmourKeys($ret->[1],$ret->[2]);
push(@uids, $ret->[0]);
push(@public, $pub );
push(@secret, $sec );
}
$info->{keyid} = $keyid;
$info->{public} = join("", @public);
$info->{secret} = join("", @secret);
$info->{uids} = \@uids;
return($info);
}
sub decryptGroupData {
my($group,$password) = @_;
my($sql,$sth,$ret,$data,$encrypt,%decArgs,$info,@groups);
$info = getGroupUsersPubkey($group);
$sql = "SELECT data
FROM gpg_group
WHERE group_name='$group' AND active";
$sth = runSQL($sql);
$ret = $sth->fetchrow_arrayref;
$info->{data} = $ret->[0];
$info->{pass} = $password;
$info->{uid} = $group;
my($dec,$valid,$sig) = gpgDecryptData($info);
return decode_base64($dec);
}
|