1package OpenXPKI::Server::Workflow::Validator::KeyParams;
2
3use strict;
4use warnings;
5use base qw( OpenXPKI::Server::Workflow::Validator );
6use Data::Dumper;
7use Crypt::PKCS10;
8use OpenXPKI::Debug;
9use OpenXPKI::Server::Context qw( CTX );
10use Workflow::Exception qw( validation_error configuration_error );
11
12
13sub _preset_args {
14    return [ qw(cert_profile pkcs10) ];
15}
16
17
18sub _validate {
19
20    ##! 1: 'start'
21    my ( $self, $wf, $cert_profile, $pkcs10 ) = @_;
22
23    if (!$pkcs10) {
24        ##! 8: 'skip - no data'
25        return 1;
26    }
27
28    my $key_alg = 'unknown';
29    my $key_params = {};
30
31    Crypt::PKCS10->setAPIversion(1);
32    my $decoded = Crypt::PKCS10->new( $pkcs10, ignoreNonBase64 => 1, verifySignature => 0);
33    if (!$decoded) {
34        validation_error('I18N_OPENXPKI_UI_VALIDATOR_KEY_PARAM_CAN_NOT_PARSE_PKCS10');
35    }
36
37    my $key_param;
38    eval {
39        $key_param = $decoded->subjectPublicKeyParams();
40    };
41
42    if (!$key_param || !$key_param->{keytype}) {
43        CTX('log')->application()->warn("Unable to get key parameters from PKCS10");
44        validation_error('I18N_OPENXPKI_UI_VALIDATOR_KEY_PARAM_ALGO_NOT_SUPPORTED');
45    } elsif ($key_param->{keytype} eq 'RSA') {
46        $key_alg = 'rsa';
47        $key_params = { key_length =>  $key_param->{keylen} };
48    } elsif ($key_param->{keytype} eq 'DSA') {
49        $key_alg = 'dsa';
50        $key_params = { key_length =>  $key_param->{keylen} };
51    } elsif ($key_param->{keytype} eq 'ECC') {
52        $key_alg = 'ec';
53        $key_params = { key_length =>  $key_param->{keylen}, curve_name => $key_param->{curve} };
54    } else {
55        validation_error('I18N_OPENXPKI_UI_VALIDATOR_KEY_PARAM_ALGO_NOT_SUPPORTED');
56    }
57
58    ##! 16: "Alg: $key_alg"
59    ##! 16: 'Params ' . Dumper $key_params
60
61    # get the list of allowed algorithms from the config
62    my $algs = CTX('api2')->get_key_algs( profile => $cert_profile, showall => 1 );
63
64    ##! 32: 'Alg expected ' . Dumper $algs
65
66    if (!grep(/\A$key_alg\z/, @{$algs})) {
67        ##! 8: "KeyParam validation failed on algo $key_alg"
68        CTX('log')->application()->error("KeyParam validation failed on algo $key_alg");
69        validation_error('I18N_OPENXPKI_UI_VALIDATOR_KEY_PARAM_ALGO_NOT_ALLOWED');
70    }
71
72    my $key_rules = CTX('api2')->get_key_params( profile => $cert_profile, alg => $key_alg, showall => 1 );
73
74    ##! 32: 'Params expected ' . Dumper $params
75
76    my $result = CTX('api2')->validate_ruleset(
77        input => $key_params,
78        ruleset => $key_rules,
79    );
80
81    if (@{$result}) {
82        my $err = '';
83        map { $err .=  $_.': '.($key_params->{$_} // '?') } @{$result};
84        CTX('log')->application()->error("KeyParam validation failed: $err");
85        validation_error("I18N_OPENXPKI_UI_VALIDATOR_KEY_PARAM_PARAM_NOT_ALLOWED ($err)");
86    }
87
88    ##! 1: 'Validation succeeded'
89    CTX('log')->application()->debug("KeyParam validation succeeded");
90
91
92    return 1;
93}
94
951;
96
97__END__
98
99=head1 NAME
100
101OpenXPKI::Server::Workflow::Validator::KeyParams
102
103=head1 Description
104
105Extracts the key parameters form the passed PKCS10 and checks them
106againstthe one of the profile.
107
108=head1 Configuration
109
110  global_validate_key_param:
111      class: OpenXPKI::Server::Workflow::Validator::KeyParams
112      arg:
113       - $cert_profile
114       - $pkcs10
115
116=head2 Arguments
117
118=over
119
120=item cert_profile
121
122Name of the certificate profile
123
124=item pkcs10
125
126PEM encoded PKCS10
127
128=back
129