From: msweet Date: Tue, 3 Sep 2013 18:50:01 +0000 (+0000) Subject: CUPS: Stop using certtool X-Git-Tag: v2.2b1~863 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e1578ed9a47f439c704e1d10eb7bd1cda2c7a23f;p=thirdparty%2Fcups.git CUPS: Stop using certtool Conditional code to use SecGenerateSelfSignedCertificate, however this API is not yet available on OS X. git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@11267 a1ca3aef-8c08-0410-bb20-df032aa958be --- diff --git a/scheduler/tls-darwin.c b/scheduler/tls-darwin.c index 9f358d9e8a..9e089d6012 100644 --- a/scheduler/tls-darwin.c +++ b/scheduler/tls-darwin.c @@ -3,7 +3,7 @@ * * TLS support code for the CUPS scheduler on OS X. * - * Copyright 2007-2012 by Apple Inc. + * Copyright 2007-2013 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -136,12 +136,12 @@ cupsdStartTLS(cupsd_client_t *con) /* I - Client connection */ if (!SSLCopyPeerTrust(con->http.tls, &peerTrust) && peerTrust) { - cupsdLogMessage(CUPSD_LOG_DEBUG, "Received %d peer certificates!", + cupsdLogMessage(CUPSD_LOG_DEBUG, "Received %d peer certificates.", (int)SecTrustGetCertificateCount(peerTrust)); CFRelease(peerTrust); } else - cupsdLogMessage(CUPSD_LOG_DEBUG, "Received NO peer certificates!"); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Received NO peer certificates."); return (1); } @@ -173,7 +173,7 @@ copy_cdsa_certificate( cupsdLogMessage(CUPSD_LOG_DEBUG, - "copy_cdsa_certificate: Looking for certs for \"%s\"...", + "copy_cdsa_certificate: Looking for certs for \"%s\".", con->servername); if ((err = SecKeychainOpen(ServerCertificate, &keychain))) @@ -229,7 +229,7 @@ copy_cdsa_certificate( snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName); cupsdLogMessage(CUPSD_LOG_DEBUG, - "copy_cdsa_certificate: Looking for certs for \"%s\"...", + "copy_cdsa_certificate: Looking for certs for \"%s\".", localname); servername = CFStringCreateWithCString(kCFAllocatorDefault, localname, @@ -264,7 +264,7 @@ copy_cdsa_certificate( if (CFGetTypeID(identity) != SecIdentityGetTypeID()) { - cupsdLogMessage(CUPSD_LOG_ERROR, "SecIdentity CFTypeID failure!"); + cupsdLogMessage(CUPSD_LOG_ERROR, "SecIdentity CFTypeID failure."); goto cleanup; } @@ -300,7 +300,141 @@ copy_cdsa_certificate( static int /* O - 1 on success, 0 on failure */ make_certificate(cupsd_client_t *con) /* I - Client connection */ { -#if 1 +# ifdef HAVE_SECGENERATESELFSIGNEDCERTIFICATE + int status = 0; /* Return status */ + OSStatus err; /* Error code (if any) */ +# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) + char localname[1024];/* Local hostname */ +# endif /* HAVE_DNSSD || HAVE_AVAHI */ + const char *servername; /* Name of server in cert */ + CFStringRef cfservername = NULL; + /* CF string for server name */ + SecIdentityRef ident = NULL; /* Identity */ + SecKeyRef publicKey = NULL, + /* Public key */ + privateKey = NULL; + /* Private key */ + CFMutableDictionaryRef keyParams = NULL; + /* Key generation parameters */ + + + cupsdLogMessage(CUPSD_LOG_INFO, + "Generating SSL server key and certificate."); + +# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) + if (con->servername && isdigit(con->servername[0] & 255) && DNSSDHostName) + { + snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName); + servername = localname; + } + else +# endif /* HAVE_DNSSD || HAVE_AVAHI */ + servername = con->servername; + + cfservername = CFStringCreateWithCString(kCFAllocatorDefault, servername, + kCFStringEncodingUTF8); + if (!cfservername) + goto cleanup; + + /* + * Create a public/private key pair... + */ + + keyParams = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + if (!keyParams) + goto cleanup; + + CFDictionaryAddValue(keyParams, kSecAttrKeyType, kSecAttrKeyTypeRSA); + CFDictionaryAddValue(keyParams, kSecAttrKeySizeInBits, CFSTR("2048")); + CFDictionaryAddValue(keyParams, kSecAttrLabel, + CFSTR("CUPS Self-Signed Certificate")); + + err = SecKeyGeneratePair(keyParams, &publicKey, &privateKey); + if (err != noErr) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, "SecKeyGeneratePair returned %ld.", + (long)err); + goto cleanup; + } + + /* + * Create a self-signed certificate using the public/private key pair... + */ + + CFIndex usageInt = kSecKeyUsageAll; + CFNumberRef usage = CFNumberCreate(alloc, kCFNumberCFIndexType, &usageInt); + CFDictionaryRef certParams = CFDictionaryCreateMutable(kCFAllocatorDefault, + kSecCSRBasicContraintsPathLen, CFINT(0), + kSecSubjectAltName, cfservername, + kSecCertificateKeyUsage, usage, + NULL, NULL); + CFRelease(usage); + + const void *ca_o[] = { kSecOidOrganization, CFSTR("") }; + const void *ca_cn[] = { kSecOidCommonName, cfservername }; + CFArrayRef ca_o_dn = CFArrayCreate(kCFAllocatorDefault, ca_o, 2, NULL); + CFArrayRef ca_cn_dn = CFArrayCreate(kCFAllocatorDefault, ca_cn, 2, NULL); + const void *ca_dn_array[2]; + + ca_dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_o_dn, + 1, NULL); + ca_dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_cn_dn, + 1, NULL); + + CFArrayRef subject = CFArrayCreate(kCFAllocatorDefault, ca_dn_array, 2, + NULL); + SecCertificateRef cert = SecGenerateSelfSignedCertificate(subject, certParams, + publicKey, + privateKey); + CFRelease(subject); + CFRelease(certParams); + + if (!cert) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, "SecGenerateSelfSignedCertificate failed."); + goto cleanup; + } + + ident = SecIdentityCreate(kCFAllocatorDefault, cert, privateKey); + + if (ident) + cupsdLogMessage(CUPSD_LOG_INFO, + "Created SSL server certificate file \"%s\".", + ServerCertificate); + + /* + * Cleanup and return... + */ + +cleanup: + + if (cfservername) + CFRelease(cfservername); + + if (keyParams) + CFRelease(keyParams); + + if (ident) + CFRelease(ident); + + if (cert) + CFRelease(cert); + + if (publicKey) + CFRelease(publicKey); + + if (privateKey) + CFRelease(publicKey); + + if (!status) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create SSL server key and certificate."); + + return (status); + +# else /* !HAVE_SECGENERATESELFSIGNEDCERTIFICATE */ int pid, /* Process ID of command */ status; /* Status of command */ char command[1024], /* Command */ @@ -308,22 +442,22 @@ make_certificate(cupsd_client_t *con) /* I - Client connection */ *envp[MAX_ENV + 1], /* Environment variables */ keychain[1024], /* Keychain argument */ infofile[1024], /* Type-in information for cert */ -# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) +# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) localname[1024], /* Local hostname */ -# endif /* HAVE_DNSSD || HAVE_AVAHI */ +# endif /* HAVE_DNSSD || HAVE_AVAHI */ *servername; /* Name of server in cert */ cups_file_t *fp; /* Seed/info file */ int infofd; /* Info file descriptor */ -# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) +# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) if (con->servername && isdigit(con->servername[0] & 255) && DNSSDHostName) { snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName); servername = localname; } else -# endif /* HAVE_DNSSD || HAVE_AVAHI */ +# endif /* HAVE_DNSSD || HAVE_AVAHI */ servername = con->servername; /* @@ -333,7 +467,7 @@ make_certificate(cupsd_client_t *con) /* I - Client connection */ if (!cupsFileFind("certtool", getenv("PATH"), 1, command, sizeof(command))) { cupsdLogMessage(CUPSD_LOG_ERROR, - "No SSL certificate and certtool command not found!"); + "No SSL certificate and certtool command not found."); return (0); } @@ -371,7 +505,7 @@ make_certificate(cupsd_client_t *con) /* I - Client connection */ cupsFileClose(fp); cupsdLogMessage(CUPSD_LOG_INFO, - "Generating SSL server key and certificate..."); + "Generating SSL server key and certificate."); snprintf(keychain, sizeof(keychain), "k=%s", ServerCertificate); @@ -409,218 +543,23 @@ make_certificate(cupsd_client_t *con) /* I - Client connection */ if (WIFEXITED(status)) cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create SSL server key and certificate - " - "the certtool command stopped with status %d!", + "the certtool command stopped with status %d.", WEXITSTATUS(status)); else cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create SSL server key and certificate - " - "the certtool command crashed on signal %d!", + "the certtool command crashed on signal %d.", WTERMSIG(status)); } else { cupsdLogMessage(CUPSD_LOG_INFO, - "Created SSL server certificate file \"%s\"...", + "Created SSL server certificate file \"%s\".", ServerCertificate); } return (!status); -#else - int status = 0; /* Return status */ - OSStatus err; /* Error code (if any) */ -# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) - char localname[1024];/* Local hostname */ -# endif /* HAVE_DNSSD || HAVE_AVAHI */ - const char *servername; /* Name of server in cert */ - CFStringRef cfservername = NULL; - /* CF string for server name */ - SecIdentityRef ident = NULL; /* Identity */ - SecKeyRef publicKey = NULL, - /* Public key */ - privateKey = NULL; - /* Private key */ - CFDictionaryRef keyParams = NULL; - /* Key generation parameters */ - - -# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) - if (con->servername && isdigit(con->servername[0] & 255) && DNSSDHostName) - { - snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName); - servername = localname; - } - else -# endif /* HAVE_DNSSD || HAVE_AVAHI */ - servername = con->servername; - - cfservername = CFStringCreateFromCString(kCFAllocatorDefault, servername, - kCFStringEncodingUTF8); - if (!cfservername) - goto cleanup; - - /* - * Create a public/private key pair... - */ - - keyParams = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks))) - if (!keyParams) - goto cleanup; - - CFDictionaryAddValue(keyParams, kSecAttrKeyType, kSecAttrKeyTypeRSA); - CFDictionaryAddValue(keyParams, kSecAttrKeySizeInBits, CFSTR("2048")); - CFDictionaryAddValue(keyParams, kSecAttrLabel, - CFSTR("CUPS Self-Signed Certificate")); - - err = SecKeyGeneratePair(keyParams, &publicKey, &privateKey); - if (err != noErr) - { - cupsdLogMessage(CUPSD_LOG_DEBUG, "SecKeyGeneratePair returned %ld.", - (long)err); - goto cleanup; - } - - /* - * Create a self-signed certificate... - */ - - CE_DataAndType exts[2], - *extp = exts; - unsigned numExts = 0; - CSSM_DATA refId; // mallocd by CSSM_TP_SubmitCredRequest - CSSM_APPLE_TP_CERT_REQUEST certReq; - CSSM_TP_REQUEST_SET reqSet; - sint32 estTime; - CSSM_BOOL confirmRequired; - CSSM_TP_RESULT_SET_PTR resultSet; - CSSM_ENCODED_CERT *encCert; - CSSM_APPLE_TP_NAME_OID subjectNames[MAX_NAMES]; - uint32 numNames = 0; - CSSM_TP_CALLERAUTH_CONTEXT CallerAuthContext; - CSSM_FIELD policyId; - - certReq.challengeString = NULL; - - extp->type = DT_KeyUsage; - extp->critical = CSSM_FALSE; - extp->extension.keyUsage = CE_KU_DigitalSignature | CE_KU_KeyCertSign | - CE_KU_KeyEncipherment | CE_KU_DataEncipherment; - extp ++; - numExts ++; - - extp->type = DT_BasicConstraints; - extp->critical = CSSM_TRUE; - extp->extension.basicConstraints.cA = CSSM_FALSE; - extp->extension.basicConstraints.pathLenConstraintPresent = CSSM_FALSE; - extp ++; - numExts ++; - - subjectNames[0].string = servername; - subjectNames[0].oid = &CSSMOID_CommonName; - subjectNames[1].string = ""; - subjectNames[1].oid = &CSSMOID_OrganizationName; - subjectNames[2].string = ""; - subjectNames[2].oid = &CSSMOID_CountryName; - subjectNames[3].string = ""; - subjectNames[3].oid = &CSSMOID_StateProvinceName; - numNames = 4; - - /* certReq */ - certReq.cspHand = cspHand; - certReq.clHand = clHand; - certReq.serialNumber = 0x12345678; // TBD - random? From user? - certReq.numSubjectNames = numNames; - certReq.subjectNames = subjectNames; - certReq.numIssuerNames = 0; - certReq.issuerNames = NULL; - certReq.issuerNameX509 = NULL; - certReq.certPublicKey = subjPubKey; - certReq.issuerPrivateKey = signerPrivKey; - certReq.signatureAlg = sigAlg; - certReq.signatureOid = *sigOid; - certReq.notBefore = 0; // TBD - from user - certReq.notAfter = 10 * 365 * 86400; - certReq.numExtensions = numExts; - certReq.extensions = exts; - reqSet.NumberOfRequests = 1; - reqSet.Requests = &certReq; - - memset(&CallerAuthContext, 0, sizeof(CSSM_TP_CALLERAUTH_CONTEXT)); - - memset(&policyId, 0, sizeof(CSSM_FIELD)); - policyId.FieldOid = CSSMOID_APPLE_TP_LOCAL_CERT_GEN; - - CallerAuthContext.Policy.NumberOfPolicyIds = 1; - CallerAuthContext.Policy.PolicyIds = &policyId; - - CSSM_RETURN crtn = CSSM_TP_SubmitCredRequest(tpHand, - NULL, // PreferredAuthority - CSSM_TP_AUTHORITY_REQUEST_CERTISSUE, - &reqSet, - &CallerAuthContext, - &estTime, - &refId); - /* before proceeding, free resources allocated thus far */ -#if CERT_TOOL - if (!useAllDefaults) { - freeNameOids(subjectNames, numNames); - } -#endif - - if (crtn) { - cuPrintError("CSSM_TP_SubmitCredRequest", crtn); - return crtn; - } - crtn = CSSM_TP_RetrieveCredResult(tpHand, - &refId, - NULL, // CallerAuthCredentials - &estTime, - &confirmRequired, - &resultSet); - if (crtn) { - cuPrintError("CSSM_TP_RetrieveCredResult", crtn); - return crtn; - } - if (resultSet == NULL) { - coreLog("httpserver", "***CSSM_TP_RetrieveCredResult returned NULL result set.\n"); - return ioErr; - } - encCert = (CSSM_ENCODED_CERT *)resultSet->Results; - *certData = encCert->CertBlob; - /* free resources allocated by TP */ - APP_FREE(refId.Data); - APP_FREE(encCert); - APP_FREE(resultSet); - return noErr; - - /* - * Cleanup and return... - */ - -cleanup: - - if (cfservername) - CFRelease(cfservername); - - if (keyParams) - CFRelease(keyParams); - - if (ident) - CFRelease(ident); - - if (publicKey) - CFRelease(publicKey); - - if (privateKey) - CFRelease(publicKey); - - if (!status) - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to create SSL server key and certificate."); - - return (status); -#endif // 0 +# endif /* HAVE_SECGENERATESELFSIGNEDCERTIFICATE */ }