⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntp_crypto.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 5 页
字号:
			fp = emalloc(len);			memcpy(fp, ep, len);			temp32 = CRYPTO_RESP;			fp->opcode |= htonl(temp32);			peer->cmmd = fp;			/* fall through */		case CRYPTO_ASSOC | CRYPTO_RESP:			/*			 * Discard the message if it has already been			 * stored or the message has been amputated.			 */			if (peer->crypto)				break;			if (vallen == 0 || vallen > MAXHOSTNAME ||			    len < VALUE_LEN + vallen) {				rval = XEVNT_LEN;				break;			}			/*			 * Check the identity schemes are compatible. If			 * the client has PC, the server must have PC,			 * in which case the server public key and			 * identity are presumed valid, so we skip the			 * certificate and identity exchanges and move			 * immediately to the cookie exchange which			 * confirms the server signature.			 */#ifdef DEBUG			if (debug)				printf(				    "crypto_recv: ident host 0x%x server 0x%x\n",				    crypto_flags, fstamp);#endif			temp32 = (crypto_flags | ident_scheme) &			    fstamp & CRYPTO_FLAG_MASK;			if (crypto_flags & CRYPTO_FLAG_PRIV) {				if (!(fstamp & CRYPTO_FLAG_PRIV)) {					rval = XEVNT_KEY;					break;				} else {					fstamp |= CRYPTO_FLAG_VALID |					    CRYPTO_FLAG_VRFY |					    CRYPTO_FLAG_SIGN;				}			/*			 * In symmetric modes it is an error if either			 * peer requests identity and the other peer			 * does not support it.			 */			} else if ((hismode == MODE_ACTIVE || hismode ==			    MODE_PASSIVE) && ((crypto_flags | fstamp) &			    CRYPTO_FLAG_MASK) && !temp32) {				rval = XEVNT_KEY;				break;			/*			 * It is an error if the client requests			 * identity and the server does not support it.			 */			} else if (hismode == MODE_CLIENT && (fstamp &			    CRYPTO_FLAG_MASK) && !temp32) {				rval = XEVNT_KEY;				break;			}			/*			 * Otherwise, the identity scheme(s) are those			 * that both client and server support.			 */			fstamp = temp32 | (fstamp & ~CRYPTO_FLAG_MASK);			/*			 * Discard the message if the signature digest			 * NID is not supported.			 */			temp32 = (fstamp >> 16) & 0xffff;			dp =			    (const EVP_MD *)EVP_get_digestbynid(temp32);			if (dp == NULL) {				rval = XEVNT_MD;				break;			}			/*			 * Save status word, host name and message			 * digest/signature type.			 */			peer->crypto = fstamp;			peer->digest = dp;			peer->subject = emalloc(vallen + 1);			memcpy(peer->subject, ep->pkt, vallen);			peer->subject[vallen] = '\0';			peer->issuer = emalloc(vallen + 1);			strcpy(peer->issuer, peer->subject);			temp32 = (fstamp >> 16) & 0xffff;			sprintf(statstr,			    "flags 0x%x host %s signature %s", fstamp,			    peer->subject, OBJ_nid2ln(temp32));			record_crypto_stats(&peer->srcadr, statstr);#ifdef DEBUG			if (debug)				printf("crypto_recv: %s\n", statstr);#endif			break;		/*		 * Decode X509 certificate in ASN.1 format and extract		 * the data containing, among other things, subject		 * name and public key. In the default identification		 * scheme, the certificate trail is followed to a self		 * signed trusted certificate.		 */		case CRYPTO_CERT | CRYPTO_RESP:			/*			 * Discard the message if invalid.			 */			if ((rval = crypto_verify(ep, NULL, peer)) !=			    XEVNT_OK)				break;			/*			 * Scan the certificate list to delete old			 * versions and link the newest version first on			 * the list.			 */			if ((rval = cert_install(ep, peer)) != XEVNT_OK)				break;			/*			 * If we snatch the certificate before the			 * server certificate has been signed by its			 * server, it will be self signed. When it is,			 * we chase the certificate issuer, which the			 * server has, and keep going until a self			 * signed trusted certificate is found. Be sure			 * to update the issuer field, since it may			 * change.			 */			if (peer->issuer != NULL)				free(peer->issuer);			peer->issuer = emalloc(strlen(cinfo->issuer) +			    1);			strcpy(peer->issuer, cinfo->issuer);			/*			 * We plug in the public key and lifetime from			 * the first certificate received. However, note			 * that this certificate might not be signed by			 * the server, so we can't check the			 * signature/digest NID.			 */			if (peer->pkey == NULL) {				ptr = (u_char *)cinfo->cert.ptr;				cert = d2i_X509(NULL, &ptr,				    ntohl(cinfo->cert.vallen));				peer->pkey = X509_get_pubkey(cert);				X509_free(cert);			}			peer->flash &= ~TEST8;			temp32 = cinfo->nid;			sprintf(statstr, "cert %s 0x%x %s (%u) fs %u",			    cinfo->subject, cinfo->flags,			    OBJ_nid2ln(temp32), temp32,			    ntohl(ep->fstamp));			record_crypto_stats(&peer->srcadr, statstr);#ifdef DEBUG			if (debug)				printf("crypto_recv: %s\n", statstr);#endif			break;		/*		 * Schnorr (IFF)identity scheme. This scheme is designed		 * for use with shared secret group keys and where the		 * certificate may be generated by a third party. The		 * client sends a challenge to the server, which		 * performs a calculation and returns the result. A		 * positive result is possible only if both client and		 * server contain the same secret group key.		 */		case CRYPTO_IFF | CRYPTO_RESP:			/*			 * Discard the message if invalid or certificate			 * trail not trusted.			 */			if (!(peer->crypto & CRYPTO_FLAG_VALID)) {				rval = XEVNT_ERR;				break;			}			if ((rval = crypto_verify(ep, NULL, peer)) !=			    XEVNT_OK)				break;			/*			 * If the the challenge matches the response,			 * the certificate public key, as well as the			 * server public key, signatyre and identity are			 * all verified at the same time. The server is			 * declared trusted, so we skip further			 * certificate stages and move immediately to			 * the cookie stage.			 */			if ((rval = crypto_iff(ep, peer)) != XEVNT_OK)				break;			peer->crypto |= CRYPTO_FLAG_VRFY |			    CRYPTO_FLAG_PROV;			peer->flash &= ~TEST8;			sprintf(statstr, "iff fs %u",			    ntohl(ep->fstamp));			record_crypto_stats(&peer->srcadr, statstr);#ifdef DEBUG			if (debug)				printf("crypto_recv: %s\n", statstr);#endif			break;		/*		 * Guillou-Quisquater (GQ) identity scheme. This scheme		 * is designed for use with public certificates carrying		 * the GQ public key in an extension field. The client		 * sends a challenge to the server, which performs a		 * calculation and returns the result. A positive result		 * is possible only if both client and server contain		 * the same group key and the server has the matching GQ		 * private key.		 */		case CRYPTO_GQ | CRYPTO_RESP:			/*			 * Discard the message if invalid or certificate			 * trail not trusted.			 */			if (!(peer->crypto & CRYPTO_FLAG_VALID)) {				rval = XEVNT_ERR;				break;			}			if ((rval = crypto_verify(ep, NULL, peer)) !=			    XEVNT_OK)				break;			/*			 * If the the challenge matches the response,			 * the certificate public key, as well as the			 * server public key, signatyre and identity are			 * all verified at the same time. The server is			 * declared trusted, so we skip further			 * certificate stages and move immediately to			 * the cookie stage.			 */			if ((rval = crypto_gq(ep, peer)) != XEVNT_OK)				break;			peer->crypto |= CRYPTO_FLAG_VRFY |			    CRYPTO_FLAG_PROV;			peer->flash &= ~TEST8;			sprintf(statstr, "gq fs %u",			    ntohl(ep->fstamp));			record_crypto_stats(&peer->srcadr, statstr);#ifdef DEBUG			if (debug)				printf("crypto_recv: %s\n", statstr);#endif			break;		/*		 * MV		 */		case CRYPTO_MV | CRYPTO_RESP:			/*			 * Discard the message if invalid or certificate			 * trail not trusted.			 */			if (!(peer->crypto & CRYPTO_FLAG_VALID)) {				rval = XEVNT_ERR;				break;			}			if ((rval = crypto_verify(ep, NULL, peer)) !=			    XEVNT_OK)				break;			/*			 * If the the challenge matches the response,			 * the certificate public key, as well as the			 * server public key, signatyre and identity are			 * all verified at the same time. The server is			 * declared trusted, so we skip further			 * certificate stages and move immediately to			 * the cookie stage.			 */			if ((rval = crypto_mv(ep, peer)) != XEVNT_OK)				break;			peer->crypto |= CRYPTO_FLAG_VRFY |			    CRYPTO_FLAG_PROV;			peer->flash &= ~TEST8;			sprintf(statstr, "mv fs %u",			    ntohl(ep->fstamp));			record_crypto_stats(&peer->srcadr, statstr);#ifdef DEBUG			if (debug)				printf("crypto_recv: %s\n", statstr);#endif			break;		/*		 * Cookie request in symmetric modes. Roll a random		 * cookie and install in symmetric mode. Encrypt for the		 * response, which is transmitted later.		 */		case CRYPTO_COOK:			/*			 * Discard the message if invalid or certificate			 * trail not trusted.			 */			if (!(peer->crypto & CRYPTO_FLAG_VALID)) {				rval = XEVNT_ERR;				break;			}			if ((rval = crypto_verify(ep, NULL, peer)) !=			    XEVNT_OK)				break;			/*			 * Pass the extension field to the transmit			 * side. If already agreed, walk away.			 */			fp = emalloc(len);			memcpy(fp, ep, len);			temp32 = CRYPTO_RESP;			fp->opcode |= htonl(temp32);			peer->cmmd = fp;			if (peer->crypto & CRYPTO_FLAG_AGREE) {				peer->flash &= ~TEST8;				break;			}			/*			 * Install cookie values and light the cookie			 * bit. The transmit side will pick up and			 * encrypt it for the response.			 */			key_expire(peer);			peer->cookval.tstamp = ep->tstamp;			peer->cookval.fstamp = ep->fstamp;			RAND_bytes((u_char *)&peer->pcookie, 4);			peer->crypto &= ~CRYPTO_FLAG_AUTO;			peer->crypto |= CRYPTO_FLAG_AGREE;			peer->flash &= ~TEST8;			sprintf(statstr, "cook %x ts %u fs %u",			    peer->pcookie, ntohl(ep->tstamp),			    ntohl(ep->fstamp));			record_crypto_stats(&peer->srcadr, statstr);#ifdef DEBUG			if (debug)				printf("crypto_recv: %s\n", statstr);#endif			break;		/*		 * Cookie response in client and symmetric modes. If the		 * cookie bit is set, the working cookie is the EXOR of		 * the current and new values.		 */		case CRYPTO_COOK | CRYPTO_RESP:			/*			 * Discard the message if invalid or identity			 * not confirmed or signature not verified with			 * respect to the cookie values.			 */			if (!(peer->crypto & CRYPTO_FLAG_VRFY)) {				rval = XEVNT_ERR;				break;			}			if ((rval = crypto_verify(ep, &peer->cookval,			    peer)) != XEVNT_OK)				break;			/*			 * Decrypt the cookie, hunting all the time for			 * errors.			 */			if (vallen == (u_int) EVP_PKEY_size(host_pkey)) {				RSA_private_decrypt(vallen,				    (u_char *)ep->pkt,				    (u_char *)&temp32,				    host_pkey->pkey.rsa,				    RSA_PKCS1_OAEP_PADDING);				cookie = ntohl(temp32);			} else {				rval = XEVNT_CKY;				break;			}			/*			 * Install cookie values and light the cookie			 * bit. If this is not broadcast client mode, we			 * are done here.			 */			key_expire(peer);			peer->cookval.tstamp = ep->tstamp;			peer->cookval.fstamp = ep->fstamp;			if (peer->crypto & CRYPTO_FLAG_AGREE)				peer->pcookie ^= cookie;			else				peer->pcookie = cookie;			if (peer->hmode == MODE_CLIENT &&			    !(peer->cast_flags & MDF_BCLNT))				peer->crypto |= CRYPTO_FLAG_AUTO;			else				peer->crypto &= ~CRYPTO_FLAG_AUTO;			peer->crypto |= CRYPTO_FLAG_AGREE;			peer->flash &= ~TEST8;			sprintf(statstr, "cook %x ts %u fs %u",			    peer->pcookie, ntohl(ep->tstamp),			    ntohl(ep->fstamp));			record_crypto_stats(&peer->srcadr, statstr);#ifdef DEBUG			if (debug)				printf("crypto_recv: %s\n", statstr);#endif			break;		/*		 * Install autokey values in broadcast client and		 * symmetric modes. We have to do this every time the		 * sever/peer cookie changes or a new keylist is		 * rolled. Ordinarily, this is automatic as this message		 * is piggybacked on the first NTP packet sent upon		 * either of these events. Note that a broadcast client		 * or symmetric peer can receive this response without a		 * matching request.		 */		case CRYPTO_AUTO | CRYPTO_RESP:			/*			 * Discard the message if invalid or identity			 * not confirmed or signature not verified with			 * respect to the receive autokey values.			 */			if (!(peer->crypto & CRYPTO_FLAG_VRFY)) {				rval = XEVNT_ERR;				break;			}			if ((rval = crypto_verify(ep, &peer->recval,			    peer)) != XEVNT_OK)				break;			/*			 * Install autokey values and light the			 * autokey bit. This is not hard.			 */			if (peer->recval.ptr == NULL)				peer->recval.ptr =				    emalloc(sizeof(struct autokey));			bp = (struct autokey *)peer->recval.ptr;			peer->recval.tstamp = ep->tstamp;			peer->recval.fstamp = ep->fstamp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -