sslauth.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:6k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  *
  33.  * $Id: sslauth.c,v 1.2 2000/09/12 20:15:42 jgmyers%netscape.com Exp $
  34.  */
  35. #include "cert.h"
  36. #include "secitem.h"
  37. #include "ssl.h"
  38. #include "sslimpl.h"
  39. #include "sslproto.h"
  40. #include "pk11func.h"
  41. /* NEED LOCKS IN HERE.  */
  42. CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd)
  43. {
  44.     sslSocket *ss;
  45.     sslSecurityInfo *sec;
  46.     ss = ssl_FindSocket(fd);
  47.     if (!ss) {
  48. SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
  49.  SSL_GETPID(), fd));
  50. return 0;
  51.     }
  52.     sec = ss->sec;
  53.     if (ss->useSecurity && sec && sec->peerCert) {
  54. return CERT_DupCertificate(sec->peerCert);
  55.     }
  56.     return 0;
  57. }
  58. /* NEED LOCKS IN HERE.  */
  59. int
  60. SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1,
  61.    char **ip, char **sp)
  62. {
  63.     sslSocket *ss;
  64.     sslSecurityInfo *sec;
  65.     const char *cipherName;
  66.     PRBool isDes = PR_FALSE;
  67.     ss = ssl_FindSocket(fd);
  68.     if (!ss) {
  69. SSL_DBG(("%d: SSL[%d]: bad socket in SecurityStatus",
  70.  SSL_GETPID(), fd));
  71. return SECFailure;
  72.     }
  73.     if (cp) *cp = 0;
  74.     if (kp0) *kp0 = 0;
  75.     if (kp1) *kp1 = 0;
  76.     if (ip) *ip = 0;
  77.     if (sp) *sp = 0;
  78.     if (op) {
  79. *op = SSL_SECURITY_STATUS_OFF;
  80.     }
  81.     if (ss->useSecurity && ss->connected) {
  82. PORT_Assert(ss->sec != 0);
  83. sec = ss->sec;
  84. if (ss->version < SSL_LIBRARY_VERSION_3_0) {
  85.     cipherName = ssl_cipherName[sec->cipherType];
  86. } else {
  87.     cipherName = ssl3_cipherName[sec->cipherType];
  88. }
  89. if (cipherName && PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE;
  90. /* do same key stuff for fortezza */
  91.     
  92. if (cp) {
  93.     *cp = PORT_Strdup(cipherName);
  94. }
  95. if (kp0) {
  96.     *kp0 = sec->keyBits;
  97.     if (isDes) *kp0 = (*kp0 * 7) / 8;
  98. }
  99. if (kp1) {
  100.     *kp1 = sec->secretKeyBits;
  101.     if (isDes) *kp1 = (*kp1 * 7) / 8;
  102. }
  103. if (op) {
  104.     if (sec->keyBits == 0) {
  105. *op = SSL_SECURITY_STATUS_OFF;
  106.     } else if (sec->secretKeyBits < 90) {
  107. *op = SSL_SECURITY_STATUS_ON_LOW;
  108.     } else {
  109. *op = SSL_SECURITY_STATUS_ON_HIGH;
  110.     }
  111. }
  112. if (ip || sp) {
  113.     CERTCertificate *cert;
  114.     cert = sec->peerCert;
  115.     if (cert) {
  116. if (ip) {
  117.     *ip = CERT_NameToAscii(&cert->issuer);
  118. }
  119. if (sp) {
  120.     *sp = CERT_NameToAscii(&cert->subject);
  121. }
  122.     } else {
  123. if (ip) {
  124.     *ip = PORT_Strdup("no certificate");
  125. }
  126. if (sp) {
  127.     *sp = PORT_Strdup("no certificate");
  128. }
  129.     }
  130. }
  131.     }
  132.     return 0;
  133. }
  134. /************************************************************************/
  135. /* NEED LOCKS IN HERE.  */
  136. int
  137. SSL_AuthCertificateHook(PRFileDesc *s, SSLAuthCertificate func, void *arg)
  138. {
  139.     sslSocket *ss;
  140.     int rv;
  141.     ss = ssl_FindSocket(s);
  142.     if (!ss) {
  143. SSL_DBG(("%d: SSL[%d]: bad socket in AuthCertificateHook",
  144.  SSL_GETPID(), s));
  145. return SECFailure;
  146.     }
  147.     if ((rv = ssl_CreateSecurityInfo(ss)) != 0) {
  148. return(rv);
  149.     }
  150.     ss->authCertificate = func;
  151.     ss->authCertificateArg = arg;
  152.     return(0);
  153. }
  154. /* NEED LOCKS IN HERE.  */
  155. int 
  156. SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func,
  157.       void *arg)
  158. {
  159.     sslSocket *ss;
  160.     int rv;
  161.     ss = ssl_FindSocket(s);
  162.     if (!ss) {
  163. SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
  164.  SSL_GETPID(), s));
  165. return SECFailure;
  166.     }
  167.     if ((rv = ssl_CreateSecurityInfo(ss)) != 0) {
  168. return rv;
  169.     }
  170.     ss->getClientAuthData = func;
  171.     ss->getClientAuthDataArg = arg;
  172.     return 0;
  173. }
  174. /* NEED LOCKS IN HERE.  */
  175. int 
  176. SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg)
  177. {
  178.     sslSocket *ss;
  179.     int rv;
  180.     ss = ssl_FindSocket(s);
  181.     if (!ss) {
  182. SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
  183.  SSL_GETPID(), s));
  184. return SECFailure;
  185.     }
  186.     if ((rv = ssl_CreateSecurityInfo(ss)) != 0) {
  187. return rv;
  188.     }
  189.     ss->pkcs11PinArg = arg;
  190.     return 0;
  191. }
  192. /* This is the "default" authCert callback function.  It is called when a 
  193.  * certificate message is received from the peer and the local application
  194.  * has not registered an authCert callback function.
  195.  */
  196. int
  197. SSL_AuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
  198. {
  199.     SECStatus          rv;
  200.     CERTCertDBHandle * handle;
  201.     sslSocket *        ss;
  202.     SECCertUsage       certUsage;
  203.     const char *             hostname    = NULL;
  204.     
  205.     ss = ssl_FindSocket(fd);
  206.     PORT_Assert(ss != NULL);
  207.     handle = (CERTCertDBHandle *)arg;
  208.     /* this may seem backwards, but isn't. */
  209.     certUsage = isServer ? certUsageSSLClient : certUsageSSLServer;
  210.     rv = CERT_VerifyCertNow(handle, ss->sec->peerCert, checkSig, certUsage,
  211.     ss->pkcs11PinArg);
  212.     if ( rv != SECSuccess || isServer )
  213. return rv;
  214.   
  215.     /* cert is OK.  This is the client side of an SSL connection.
  216.      * Now check the name field in the cert against the desired hostname.
  217.      * NB: This is our only defense against Man-In-The-Middle (MITM) attacks!
  218.      */
  219.     hostname = ss->url;
  220.     if (hostname && hostname[0])
  221. rv = CERT_VerifyCertName(ss->sec->peerCert, hostname);
  222.     else 
  223. rv = SECFailure;
  224.     if (rv != SECSuccess)
  225. PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
  226.     return rv;
  227. }