15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "Default" SSLSocket methods, used by sockets that do neither SSL nor socks. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This Source Code Form is subject to the terms of the Mozilla Public 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * License, v. 2.0. If a copy of the MPL was not distributed with this 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "cert.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ssl.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslimpl.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(WIN32) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAP_ERROR(from,to) if (err == from) { PORT_SetError(to); } 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEFINE_ERROR PRErrorCode err = PR_GetError(); 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAP_ERROR(from,to) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEFINE_ERROR 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRFileDesc *lower = ss->fd->lower; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = lower->methods->connect(lower, sa, ss->cTimeout); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRFileDesc *lower = ss->fd->lower; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = lower->methods->bind(lower, addr); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ssl_DefListen(sslSocket *ss, int backlog) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRFileDesc *lower = ss->fd->lower; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = lower->methods->listen(lower, backlog); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ssl_DefShutdown(sslSocket *ss, int how) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRFileDesc *lower = ss->fd->lower; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = lower->methods->shutdown(lower, how); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRFileDesc *lower = ss->fd->lower; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = lower->methods->recv(lower, (void *)buf, len, flags, ss->rTimeout); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv < 0) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_ERROR 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (rv > len) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(rv <= len); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_BUFFER_OVERFLOW_ERROR); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECFailure; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Default (unencrypted) send. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For blocking sockets, always returns len or SECFailure, no short writes. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For non-blocking sockets: 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns positive count if any data was written, else returns SECFailure. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Short writes may occur. Does not return SECWouldBlock. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRFileDesc *lower = ss->fd->lower; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sent = 0; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if NSS_DISABLE_NAGLE_DELAYS 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Although this is overkill, we disable Nagle delays completely for 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** SSL sockets. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.useSecurity && !ss->delayDisabled) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_EnableNagleDelay(ss, PR_FALSE); /* ignore error */ 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->delayDisabled = 1; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = lower->methods->send(lower, (const void *)(buf + sent), 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len - sent, flags, ss->wTimeout); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv < 0) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRErrorCode err = PR_GetError(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err == PR_WOULD_BLOCK_ERROR) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->lastWriteBlocked = 1; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sent ? sent : SECFailure; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->lastWriteBlocked = 0; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Loser */ 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sent += rv; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IS_DTLS(ss) && (len > sent)) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We got a partial write so just return it */ 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sent; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (len > sent); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->lastWriteBlocked = 0; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sent; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRFileDesc *lower = ss->fd->lower; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = lower->methods->read(lower, (void *)buf, len); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv < 0) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_ERROR 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRFileDesc *lower = ss->fd->lower; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sent = 0; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = lower->methods->write(lower, (const void *)(buf + sent), 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len - sent); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv < 0) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRErrorCode err = PR_GetError(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err == PR_WOULD_BLOCK_ERROR) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->lastWriteBlocked = 1; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sent ? sent : SECFailure; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->lastWriteBlocked = 0; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Loser */ 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sent += rv; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (len > sent); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->lastWriteBlocked = 0; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sent; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRFileDesc *lower = ss->fd->lower; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = lower->methods->getpeername(lower, name); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRFileDesc *lower = ss->fd->lower; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = lower->methods->getsockname(lower, name); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ssl_DefClose(sslSocket *ss) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRFileDesc *fd; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRFileDesc *popped; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd = ss->fd; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* First, remove the SSL layer PRFileDesc from the socket's stack, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** then invoke the SSL layer's PRFileDesc destructor. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** This must happen before the next layer down is closed. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(fd->higher == NULL); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fd->higher) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_BAD_DESCRIPTOR_ERROR); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->fd = NULL; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* PR_PopIOLayer will swap the contents of the top two PRFileDescs on 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the stack, and then remove the second one. This way, the address 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** of the PRFileDesc on the top of the stack doesn't change. 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popped->dtor(popped); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* fd is now the PRFileDesc for the next layer down. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Now close the underlying socket. 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = fd->methods->close(fd); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_FreeSocket(ss); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_TRC(5, ("%d: SSL[%d]: closing, rv=%d errno=%d", 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), fd, rv, PORT_GetError())); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 211