2 * Copyright (c) 2011, JANET(UK)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of JANET(UK) nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include "gssapiP_eap.h"
34 #include <openssl/bio.h>
35 #include <openssl/pem.h>
36 #include <openssl/x509.h>
38 #ifdef HAVE_MOONSHOT_GET_IDENTITY
39 #include <libmoonshot.h>
42 libMoonshotMapError(OM_uint32 *minor,
43 MoonshotError **pError)
45 MoonshotError *error = *pError;
47 GSSEAP_ASSERT(error != NULL);
49 switch (error->code) {
50 case MOONSHOT_ERROR_UNABLE_TO_START_SERVICE:
51 *minor = GSSEAP_UNABLE_TO_START_IDENTITY_SERVICE;
53 case MOONSHOT_ERROR_NO_IDENTITY_SELECTED:
54 *minor = GSSEAP_NO_IDENTITY_SELECTED;
56 case MOONSHOT_ERROR_INSTALLATION_ERROR:
57 *minor = GSSEAP_IDENTITY_SERVICE_INSTALL_ERROR;
59 case MOONSHOT_ERROR_OS_ERROR:
60 *minor = GSSEAP_IDENTITY_SERVICE_OS_ERROR;
62 case MOONSHOT_ERROR_IPC_ERROR:
63 *minor = GSSEAP_IDENTITY_SERVICE_IPC_ERROR;
66 *minor = GSSEAP_IDENTITY_SERVICE_UNKNOWN_ERROR;
70 gssEapSaveStatusInfo(*minor, error->message);
71 moonshot_error_free(error);
74 return GSS_S_CRED_UNAVAIL;
78 libMoonshotResolveDefaultIdentity(OM_uint32 *minor,
79 const gss_cred_id_t cred,
82 OM_uint32 major, tmpMinor;
83 gss_OID nameMech = gssEapPrimaryMechForCred(cred);
84 gss_name_t name = GSS_C_NO_NAME;
85 gss_buffer_desc tmpBuffer = GSS_C_EMPTY_BUFFER;
87 char *password = NULL;
88 char *serverCertificateHash = NULL;
89 char *caCertificate = NULL;
90 char *subjectNameConstraint = NULL;
91 char *subjectAltNameConstraint = NULL;
92 MoonshotError *error = NULL;
94 *pName = GSS_C_NO_NAME;
96 if (!moonshot_get_default_identity(&nai,
98 &serverCertificateHash,
100 &subjectNameConstraint,
101 &subjectAltNameConstraint,
103 if (error->code == MOONSHOT_ERROR_NO_IDENTITY_SELECTED) {
104 major = GSS_S_CRED_UNAVAIL;
105 *minor = GSSEAP_NO_DEFAULT_IDENTITY;
106 moonshot_error_free(error);
108 major = libMoonshotMapError(minor, &error);
112 tmpBuffer.value = nai;
113 tmpBuffer.length = strlen(nai);
115 major = gssEapImportName(minor, &tmpBuffer, GSS_C_NT_USER_NAME, nameMech, &name);
116 if (GSS_ERROR(major))
120 name = GSS_C_NO_NAME;
124 moonshot_free(password);
125 moonshot_free(serverCertificateHash);
126 moonshot_free(caCertificate);
127 moonshot_free(subjectNameConstraint);
128 moonshot_free(subjectAltNameConstraint);
130 gssEapReleaseName(&tmpMinor, &name);
135 static int stringEmpty(const char * s)
145 libMoonshotResolveInitiatorCred(OM_uint32 *minor,
147 const gss_name_t targetName)
149 OM_uint32 major, tmpMinor;
150 gss_OID nameMech = gssEapPrimaryMechForCred(cred);
151 gss_buffer_desc initiator = GSS_C_EMPTY_BUFFER;
152 gss_buffer_desc target = GSS_C_EMPTY_BUFFER;
153 gss_buffer_desc tmpBuffer = GSS_C_EMPTY_BUFFER;
155 char *password = NULL;
156 char *serverCertificateHash = NULL;
157 char *caCertificate = NULL;
158 char *subjectNameConstraint = NULL;
159 char *subjectAltNameConstraint = NULL;
160 MoonshotError *error = NULL;
163 if (cred->name != GSS_C_NO_NAME) {
164 major = gssEapDisplayName(minor, cred->name, &initiator, NULL);
165 if (GSS_ERROR(major))
169 if (targetName != GSS_C_NO_NAME) {
170 major = gssEapDisplayName(minor, targetName, &target, NULL);
171 if (GSS_ERROR(major))
175 if (!moonshot_get_identity((const char *)initiator.value,
176 (const char *)cred->password.value,
177 (const char *)target.value,
180 &serverCertificateHash,
182 &subjectNameConstraint,
183 &subjectAltNameConstraint,
185 major = libMoonshotMapError(minor, &error);
189 gssEapReleaseName(&tmpMinor, &cred->name);
191 tmpBuffer.value = nai;
192 tmpBuffer.length = strlen(nai);
194 major = gssEapImportName(minor, &tmpBuffer, GSS_C_NT_USER_NAME,
195 nameMech, &cred->name);
196 if (GSS_ERROR(major))
199 tmpBuffer.value = password;
200 tmpBuffer.length = strlen(password);
202 major = gssEapSetCredPassword(minor, cred, &tmpBuffer);
203 if (GSS_ERROR(major))
206 gss_release_buffer(&tmpMinor, &cred->caCertificate);
207 gss_release_buffer(&tmpMinor, &cred->caCertificateBlob);
208 gss_release_buffer(&tmpMinor, &cred->subjectNameConstraint);
209 gss_release_buffer(&tmpMinor, &cred->subjectAltNameConstraint);
211 if (!stringEmpty(serverCertificateHash)) {
212 size_t len = strlen(serverCertificateHash);
214 #define HASH_PREFIX "hash://server/sha256/"
215 #define HASH_PREFIX_LEN (sizeof(HASH_PREFIX) - 1)
217 cred->caCertificate.value = GSSEAP_MALLOC(HASH_PREFIX_LEN + len + 1);
218 if (cred->caCertificate.value == NULL) {
219 major = GSS_S_FAILURE;
224 memcpy(cred->caCertificate.value, HASH_PREFIX, HASH_PREFIX_LEN);
225 memcpy((char *)cred->caCertificate.value + HASH_PREFIX_LEN, serverCertificateHash, len);
227 ((char *)cred->caCertificate.value)[HASH_PREFIX_LEN + len] = '\0';
229 cred->caCertificate.length = HASH_PREFIX_LEN + len;
230 } else if (!stringEmpty(caCertificate)) {
235 bio = BIO_new_mem_buf(caCertificate, -1);
237 major = GSS_S_FAILURE;
241 cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
243 major = GSS_S_FAILURE;
248 bio = BIO_new(BIO_s_mem());
249 if (i2d_X509_bio(bio, cert) < 0) {
250 major = GSS_S_FAILURE;
251 *minor = ENOMEM; /* TODO */
254 BIO_get_mem_ptr(bio, &bptr);
255 tmp.value = bptr->data;
256 tmp.length = bptr->length;
257 major = duplicateBuffer(minor, &tmp, &cred->caCertificateBlob);
258 if (major != GSS_S_COMPLETE) {
262 makeStringBufferOrCleanup("blob://ca-cert", &cred->caCertificate);
265 if (!stringEmpty(subjectNameConstraint))
266 makeStringBufferOrCleanup(subjectNameConstraint, &cred->subjectNameConstraint);
267 if (!stringEmpty(subjectAltNameConstraint))
268 makeStringBufferOrCleanup(subjectAltNameConstraint, &cred->subjectAltNameConstraint);
272 moonshot_free(password);
273 moonshot_free(serverCertificateHash);
274 moonshot_free(caCertificate);
275 moonshot_free(subjectNameConstraint);
276 moonshot_free(subjectAltNameConstraint);
279 gss_release_buffer(&tmpMinor, &initiator);
280 gss_release_buffer(&tmpMinor, &target);
284 #endif /* HAVE_MOONSHOT_GET_IDENTITY */