1 package Crypt::Monkeysphere::Validator;
6 use parent 'Crypt::Monkeysphere::Keyserver';
12 Create a new Crypt::Monkeysphere::Validator instance
16 Param hash, all optional.
18 context => 'e-mail|https|ssh|...'
19 control what counts as suitable user IDs and key capabilities.
21 kspolicy => 'always|never|unlessvalid'
22 when to fetch keys and key updates from keyserver.
24 (plus arguments for Crypt::Monkeysphere::{Keyserver,Logger}::new )
32 uid => (mandatory) OpenPGP User ID desired.
34 fpr => fingerprint of the key to compare
36 key => hash of pubkey parameters as Math::BigInt values
38 one of either fpr or key must be supplied.
44 If the lookup succeeded, then the hashref has a key named
45 valid_key that points to a hashref { fingerprint => $fpr, val =>
48 If no fully-valid keys+userid were found, but some keys matched
49 with less-than-valid user IDs, then the hashref has a key named
50 subvalid_keys that points to an arrayref of { fingerprint => $fpr,
51 val => $validity } hashrefs.
59 my $self=$class->SUPER::new(%opts);
61 $self->{context}=$opts{context} || 'ssh';
62 $self->{kspolicy}=$opts{kspolicy} || 'unlessvalid';
70 if ($self->{context} eq 'e-mail') {
71 if ($subkey->usage_flags =~ /s/) {
72 $self->log('verbose', "...and is signing-capable...\n");
75 $self->log('verbose', "...but is not signing-capable (%s).\n",$subkey->usage_flags);
78 if ($subkey->usage_flags =~ /a/) {
79 $self->log('verbose', "...and is authentication-capable...\n");
82 $self->log('verbose', "...but is not authentication-capable (%s).\n",$subkey->usage_flags);
92 my $uid=$args{uid} || croak "uid argument is mandatory";
95 defined($fpr) || defined($key) || croak "Must supply either a fingerprint or a key";
97 my $subvalid_keys = [];
99 my $gpgquery = defined($fpr) ? '0x'.$fpr : '='.$uid;
101 foreach my $gpgkey ($self->{gnupg}->get_public_keys($gpgquery)) {
103 foreach my $tryuid ($gpgkey->user_ids) {
104 if ($tryuid->as_string eq $uid) {
105 $validity = $tryuid->validity;
108 # treat primary keys just like subkeys:
109 foreach my $subkey ($gpgkey, @{$gpgkey->subkeys}) {
110 if ((defined($key) && $self->keycomp($key, $subkey)) ||
111 (defined($fpr) && ($subkey->fingerprint->as_hex_string eq $fpr))) {
112 $self->log('verbose', "key 0x%s matches...\n",$subkey->hex_id);
113 if ($self->test_capable($subkey) ) {
114 if ($validity =~ /^[fu]$/) {
115 $self->log('verbose', "...and is fully valid!\n");
116 # we have a key that matches with a valid userid -- no need to look further.
117 return {valid_key => { fingerprint => $subkey->fingerprint, val => $validity }};
119 $self->log('verbose', "...but is not fully valid (%s).\n",$validity);
120 push(@{$subvalid_keys},
121 {fingerprint => $subkey->fingerprint, val => $validity });
127 return { subvalid_keys => $subvalid_keys };
134 if ($self->{kspolicy} eq 'unlessvalid') {
135 my $ret = $self->_tryquery(uid => $opts{uid}, fpr => $opts{fpr}, key => $opts{key});
137 if exists($ret->{valid_key});
140 if ($self->{kspolicy} ne 'never') {
141 if (defined($opts{fpr})) {
142 $self->fetch_fpr($opts{fpr});
144 $self->fetch_uid($opts{uid});
147 return $self->_tryquery(uid => $opts{uid}, fpr => $opts{fpr}, key => $opts{key});
155 if ($gpgkey->algo_num != 1) {
156 my $self->log('verbose', "Monkeysphere only does RSA keys. This key is algorithm #%d\n", $gpgkey->algo_num);
158 if ($rsakey->{exponent}->bcmp($gpgkey->pubkey_data->[1]) == 0 &&
159 $rsakey->{modulus}->bcmp($gpgkey->pubkey_data->[0]) == 0) {