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>
39 #ifdef HAVE_MOONSHOT_GET_IDENTITY
40 #include <libmoonshot.h>
43 libMoonshotMapError(OM_uint32 *minor,
44 MoonshotError **pError)
46 MoonshotError *error = *pError;
48 GSSEAP_ASSERT(error != NULL);
50 switch (error->code) {
51 case MOONSHOT_ERROR_UNABLE_TO_START_SERVICE:
52 *minor = GSSEAP_UNABLE_TO_START_IDENTITY_SERVICE;
54 case MOONSHOT_ERROR_NO_IDENTITY_SELECTED:
55 *minor = GSSEAP_NO_IDENTITY_SELECTED;
57 case MOONSHOT_ERROR_INSTALLATION_ERROR:
58 *minor = GSSEAP_IDENTITY_SERVICE_INSTALL_ERROR;
60 case MOONSHOT_ERROR_OS_ERROR:
61 *minor = GSSEAP_IDENTITY_SERVICE_OS_ERROR;
63 case MOONSHOT_ERROR_IPC_ERROR:
64 *minor = GSSEAP_IDENTITY_SERVICE_IPC_ERROR;
67 *minor = GSSEAP_IDENTITY_SERVICE_UNKNOWN_ERROR;
71 gssEapSaveStatusInfo(*minor, error->message);
72 moonshot_error_free(error);
75 return GSS_S_CRED_UNAVAIL;
79 libMoonshotResolveDefaultIdentity(OM_uint32 *minor,
80 const gss_cred_id_t cred,
83 OM_uint32 major, tmpMinor;
84 gss_OID nameMech = gssEapPrimaryMechForCred(cred);
85 gss_name_t name = GSS_C_NO_NAME;
86 gss_buffer_desc tmpBuffer = GSS_C_EMPTY_BUFFER;
88 char *password = NULL;
89 char *serverCertificateHash = NULL;
90 char *caCertificate = NULL;
91 char *subjectNameConstraint = NULL;
92 char *subjectAltNameConstraint = NULL;
93 MoonshotError *error = NULL;
95 *pName = GSS_C_NO_NAME;
97 if (!moonshot_get_default_identity(&nai,
99 &serverCertificateHash,
101 &subjectNameConstraint,
102 &subjectAltNameConstraint,
104 if (error->code == MOONSHOT_ERROR_NO_IDENTITY_SELECTED) {
105 major = GSS_S_CRED_UNAVAIL;
106 *minor = GSSEAP_NO_DEFAULT_IDENTITY;
107 moonshot_error_free(error);
109 major = libMoonshotMapError(minor, &error);
113 tmpBuffer.value = nai;
114 tmpBuffer.length = strlen(nai);
116 major = gssEapImportName(minor, &tmpBuffer, GSS_C_NT_USER_NAME, nameMech, &name);
117 if (GSS_ERROR(major))
121 name = GSS_C_NO_NAME;
125 moonshot_free(password);
126 moonshot_free(serverCertificateHash);
127 moonshot_free(caCertificate);
128 moonshot_free(subjectNameConstraint);
129 moonshot_free(subjectAltNameConstraint);
131 gssEapReleaseName(&tmpMinor, &name);
136 static int stringEmpty(const char * s)
146 libMoonshotResolveInitiatorCred(OM_uint32 *minor,
148 const gss_name_t targetName)
150 OM_uint32 major, tmpMinor;
151 gss_OID nameMech = gssEapPrimaryMechForCred(cred);
152 gss_buffer_desc initiator = GSS_C_EMPTY_BUFFER;
153 gss_buffer_desc target = GSS_C_EMPTY_BUFFER;
154 gss_buffer_desc tmpBuffer = GSS_C_EMPTY_BUFFER;
156 char *password = NULL;
157 char *serverCertificateHash = NULL;
158 char *caCertificate = NULL;
159 char *subjectNameConstraint = NULL;
160 char *subjectAltNameConstraint = NULL;
161 MoonshotError *error = NULL;
164 if (cred->name != GSS_C_NO_NAME) {
165 major = gssEapDisplayName(minor, cred->name, &initiator, NULL);
166 if (GSS_ERROR(major))
170 if (targetName != GSS_C_NO_NAME) {
171 major = gssEapDisplayName(minor, targetName, &target, NULL);
172 if (GSS_ERROR(major))
176 if (!moonshot_get_identity((const char *)initiator.value,
177 (const char *)cred->password.value,
178 (const char *)target.value,
181 &serverCertificateHash,
183 &subjectNameConstraint,
184 &subjectAltNameConstraint,
186 major = libMoonshotMapError(minor, &error);
190 gssEapReleaseName(&tmpMinor, &cred->name);
192 tmpBuffer.value = nai;
193 tmpBuffer.length = strlen(nai);
195 major = gssEapImportName(minor, &tmpBuffer, GSS_C_NT_USER_NAME,
196 nameMech, &cred->name);
197 if (GSS_ERROR(major))
200 tmpBuffer.value = password;
201 tmpBuffer.length = strlen(password);
203 major = gssEapSetCredPassword(minor, cred, &tmpBuffer);
204 if (GSS_ERROR(major))
207 gss_release_buffer(&tmpMinor, &cred->caCertificate);
208 gss_release_buffer(&tmpMinor, &cred->caCertificateBlob);
209 gss_release_buffer(&tmpMinor, &cred->subjectNameConstraint);
210 gss_release_buffer(&tmpMinor, &cred->subjectAltNameConstraint);
212 if (!stringEmpty(serverCertificateHash)) {
213 size_t len = strlen(serverCertificateHash);
215 #define HASH_PREFIX "hash://server/sha256/"
216 #define HASH_PREFIX_LEN (sizeof(HASH_PREFIX) - 1)
218 cred->caCertificate.value = GSSEAP_MALLOC(HASH_PREFIX_LEN + len + 1);
219 if (cred->caCertificate.value == NULL) {
220 major = GSS_S_FAILURE;
225 memcpy(cred->caCertificate.value, HASH_PREFIX, HASH_PREFIX_LEN);
226 memcpy((char *)cred->caCertificate.value + HASH_PREFIX_LEN, serverCertificateHash, len);
228 ((char *)cred->caCertificate.value)[HASH_PREFIX_LEN + len] = '\0';
230 cred->caCertificate.length = HASH_PREFIX_LEN + len;
231 } else if (!stringEmpty(caCertificate)) {
236 bio = BIO_new_mem_buf(caCertificate, -1);
238 major = GSS_S_FAILURE;
242 cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
244 major = GSS_S_DEFECTIVE_CREDENTIAL;
245 *minor = GSSEAP_BAD_CACERTIFICATE;
249 bio = BIO_new(BIO_s_mem());
250 if (i2d_X509_bio(bio, cert) < 0) {
251 major = GSS_S_DEFECTIVE_CREDENTIAL;
252 *minor = GSSEAP_BAD_CACERTIFICATE;
255 BIO_get_mem_ptr(bio, &bptr);
256 tmp.value = bptr->data;
257 tmp.length = bptr->length;
258 major = duplicateBuffer(minor, &tmp, &cred->caCertificateBlob);
259 if (major != GSS_S_COMPLETE) {
264 makeStringBufferOrCleanup("blob://ca-cert", &cred->caCertificate);
267 if (!stringEmpty(subjectNameConstraint))
268 makeStringBufferOrCleanup(subjectNameConstraint, &cred->subjectNameConstraint);
269 if (!stringEmpty(subjectAltNameConstraint))
270 makeStringBufferOrCleanup(subjectAltNameConstraint, &cred->subjectAltNameConstraint);
274 moonshot_free(password);
275 moonshot_free(serverCertificateHash);
276 moonshot_free(caCertificate);
277 moonshot_free(subjectNameConstraint);
278 moonshot_free(subjectAltNameConstraint);
281 gss_release_buffer(&tmpMinor, &initiator);
282 gss_release_buffer(&tmpMinor, &target);
286 #endif /* HAVE_MOONSHOT_GET_IDENTITY */