]>
Commit | Line | Data |
---|---|---|
382b4817 | 1 | /** |
f27f6296 | 2 | * @file rsa_authenticator.c |
382b4817 | 3 | * |
f27f6296 | 4 | * @brief Implementation of rsa_authenticator_t. |
382b4817 MW |
5 | * |
6 | */ | |
7 | ||
8 | /* | |
9 | * Copyright (C) 2005-2006 Martin Willi | |
10 | * Copyright (C) 2005 Jan Hutter | |
11 | * Hochschule fuer Technik Rapperswil | |
12 | * | |
13 | * This program is free software; you can redistribute it and/or modify it | |
14 | * under the terms of the GNU General Public License as published by the | |
15 | * Free Software Foundation; either version 2 of the License, or (at your | |
16 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
17 | * | |
18 | * This program is distributed in the hope that it will be useful, but | |
19 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
20 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
21 | * for more details. | |
22 | */ | |
23 | ||
24 | #include <string.h> | |
25 | ||
26 | #include "rsa_authenticator.h" | |
27 | ||
382b4817 MW |
28 | #include <daemon.h> |
29 | ||
30 | ||
31 | typedef struct private_rsa_authenticator_t private_rsa_authenticator_t; | |
32 | ||
33 | /** | |
34 | * Private data of an rsa_authenticator_t object. | |
35 | */ | |
36 | struct private_rsa_authenticator_t { | |
37 | ||
38 | /** | |
39 | * Public authenticator_t interface. | |
40 | */ | |
41 | rsa_authenticator_t public; | |
42 | ||
43 | /** | |
44 | * Assigned IKE_SA | |
45 | */ | |
46 | ike_sa_t *ike_sa; | |
47 | }; | |
48 | ||
49 | /** | |
f27f6296 | 50 | * Function implemented in psk_authenticator.c |
382b4817 | 51 | */ |
f27f6296 MW |
52 | extern chunk_t build_tbs_octets(chunk_t ike_sa_init, chunk_t nonce, |
53 | identification_t *id, prf_t *prf); | |
382b4817 MW |
54 | |
55 | /** | |
56 | * Implementation of authenticator_t.verify. | |
57 | */ | |
58 | static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init, | |
59 | chunk_t my_nonce, auth_payload_t *auth_payload) | |
60 | { | |
61 | status_t status; | |
62 | chunk_t auth_data, octets; | |
63 | rsa_public_key_t *public_key; | |
64 | identification_t *other_id; | |
65 | ||
66 | other_id = this->ike_sa->get_other_id(this->ike_sa); | |
67 | ||
68 | if (auth_payload->get_auth_method(auth_payload) != AUTH_RSA) | |
69 | { | |
70 | return INVALID_ARG; | |
71 | } | |
72 | auth_data = auth_payload->get_data(auth_payload); | |
73 | public_key = charon->credentials->get_trusted_public_key(charon->credentials, | |
74 | other_id); | |
75 | if (public_key == NULL) | |
76 | { | |
77 | DBG1(DBG_IKE, "no RSA public key found for '%D'", other_id); | |
78 | return NOT_FOUND; | |
79 | } | |
f27f6296 | 80 | octets = build_tbs_octets(ike_sa_init, my_nonce, other_id, |
382b4817 MW |
81 | this->ike_sa->get_auth_verify(this->ike_sa)); |
82 | status = public_key->verify_emsa_pkcs1_signature(public_key, octets, auth_data); | |
83 | chunk_free(&octets); | |
84 | ||
85 | if (status != SUCCESS) | |
86 | { | |
87 | DBG1(DBG_IKE, "RSA signature verification failed"); | |
88 | return status; | |
89 | } | |
90 | ||
91 | DBG1(DBG_IKE, "authentication of '%D' with %N successful", | |
92 | other_id, auth_method_names, AUTH_RSA); | |
93 | return SUCCESS; | |
94 | } | |
95 | ||
96 | /** | |
97 | * Implementation of authenticator_t.build. | |
98 | */ | |
99 | static status_t build(private_rsa_authenticator_t *this, chunk_t ike_sa_init, | |
100 | chunk_t other_nonce, auth_payload_t **auth_payload) | |
101 | { | |
102 | chunk_t chunk; | |
103 | chunk_t octets; | |
104 | chunk_t auth_data; | |
105 | status_t status; | |
106 | rsa_public_key_t *my_pubkey; | |
107 | rsa_private_key_t *my_key; | |
108 | identification_t *my_id; | |
109 | ||
110 | my_id = this->ike_sa->get_my_id(this->ike_sa); | |
914eea92 | 111 | DBG1(DBG_IKE, "authentication of '%D' (myself) with %N", |
382b4817 MW |
112 | my_id, auth_method_names, AUTH_RSA); |
113 | DBG2(DBG_IKE, "looking for RSA public key belonging to '%D'", my_id); | |
114 | ||
115 | my_pubkey = charon->credentials->get_rsa_public_key(charon->credentials, my_id); | |
116 | if (my_pubkey == NULL) | |
117 | { | |
118 | DBG1(DBG_IKE, "no RSA public key found for '%D'", my_id); | |
119 | return NOT_FOUND; | |
120 | } | |
121 | DBG2(DBG_IKE, "matching RSA public key found"); | |
122 | chunk = my_pubkey->get_keyid(my_pubkey); | |
123 | DBG2(DBG_IKE, "looking for RSA private key with keyid %#B", &chunk); | |
124 | my_key = charon->credentials->get_rsa_private_key(charon->credentials, my_pubkey); | |
125 | if (my_key == NULL) | |
126 | { | |
127 | DBG1(DBG_IKE, "no RSA private key found with for %D with keyid %#B", | |
128 | my_id, &chunk); | |
129 | return NOT_FOUND; | |
130 | } | |
131 | DBG2(DBG_IKE, "matching RSA private key found"); | |
132 | ||
f27f6296 | 133 | octets = build_tbs_octets(ike_sa_init, other_nonce, my_id, |
382b4817 MW |
134 | this->ike_sa->get_auth_build(this->ike_sa)); |
135 | status = my_key->build_emsa_pkcs1_signature(my_key, HASH_SHA1, octets, &auth_data); | |
136 | chunk_free(&octets); | |
137 | ||
138 | if (status != SUCCESS) | |
139 | { | |
140 | my_key->destroy(my_key); | |
141 | DBG1(DBG_IKE, "build signature of SHA1 hash failed"); | |
142 | return status; | |
143 | } | |
144 | DBG2(DBG_IKE, "successfully signed with RSA private key"); | |
145 | ||
146 | *auth_payload = auth_payload_create(); | |
147 | (*auth_payload)->set_auth_method(*auth_payload, AUTH_RSA); | |
148 | (*auth_payload)->set_data(*auth_payload, auth_data); | |
149 | ||
150 | my_key->destroy(my_key); | |
151 | chunk_free(&auth_data); | |
152 | return SUCCESS; | |
153 | } | |
154 | ||
155 | /** | |
156 | * Implementation of authenticator_t.destroy. | |
157 | */ | |
158 | static void destroy(private_rsa_authenticator_t *this) | |
159 | { | |
160 | free(this); | |
161 | } | |
162 | ||
163 | /* | |
164 | * Described in header. | |
165 | */ | |
166 | rsa_authenticator_t *rsa_authenticator_create(ike_sa_t *ike_sa) | |
167 | { | |
168 | private_rsa_authenticator_t *this = malloc_thing(private_rsa_authenticator_t); | |
169 | ||
170 | /* public functions */ | |
171 | this->public.authenticator_interface.verify = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t*))verify; | |
172 | this->public.authenticator_interface.build = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t**))build; | |
173 | this->public.authenticator_interface.destroy = (void(*)(authenticator_t*))destroy; | |
174 | ||
175 | /* private data */ | |
176 | this->ike_sa = ike_sa; | |
177 | ||
178 | return &this->public; | |
179 | } |