]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
<rdar://problem/11044332> CUPS: Stop using certtool
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Tue, 3 Sep 2013 18:50:01 +0000 (18:50 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Tue, 3 Sep 2013 18:50:01 +0000 (18:50 +0000)
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

scheduler/tls-darwin.c

index 9f358d9e8ab673b178a69627f9fdcf3697e5e206..9e089d6012e6e135f3f3e68327d9ad4f6f9a7b82 100644 (file)
@@ -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 */
 }