FreeBSD/contrib/ntp/ntpd/ntp_crypto.c
/*
 * crypto_gq - verify Bob's response to Alice's challenge
 *
 * Returns
 * XEVNT_OK	success
 * XEVNT_ERR	protocol error
 * XEVNT_FSP	bad filestamp
 * XEVNT_ID	bad or missing group keys
 * XEVNT_PUB	bad or missing public key
 */
verify Bob's response to Alice's challenge
Returns
XEVNT_OK     success
XEVNT_ERR    protocol error
XEVNT_FSP    bad filestamp
XEVNT_ID     bad or missing group keys
XEVNT_PUB    bad or missing public key
verify Bob ' s response to Alice ' s challenge Returns XEVNT_OK success XEVNT_ERR protocol error XEVNT_FSP bad filestamp XEVNT_ID bad or missing group keys XEVNT_PUB bad or missing public key
int
crypto_gq(
	struct exten *ep,	
	struct peer *peer	
	)
{
	RSA	*rsa;		
	BN_CTX	*bctx;		
	DSA_SIG	*sdsa;		
	BIGNUM	*y, *v;
	const u_char *ptr;
	long	len;
	u_int	temp;
	const BIGNUM *n, *e;
	const BIGNUM *r, *s;
	if (peer->ident_pkey == NULL) {
		msyslog(LOG_NOTICE, "crypto_gq: scheme unavailable");
		return (XEVNT_ID);
	}
	if (ntohl(ep->fstamp) < peer->ident_pkey->fstamp) {
		msyslog(LOG_NOTICE, "crypto_gq: invalid filestamp %u",
		    ntohl(ep->fstamp));
		return (XEVNT_FSP);
	}
	if ((rsa = EVP_PKEY_get0_RSA(peer->ident_pkey->pkey)) == NULL) {
		msyslog(LOG_NOTICE, "crypto_gq: defective key");
		return (XEVNT_PUB);
	}
	RSA_get0_key(rsa, &n, NULL, &e);
	if (peer->iffval == NULL) {
		msyslog(LOG_NOTICE, "crypto_gq: missing challenge");
		return (XEVNT_ID);
	}
	bctx = BN_CTX_new(); y = BN_new(); v = BN_new();
	len = ntohl(ep->vallen);
	ptr = (u_char *)ep->pkt;
	if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) {
		BN_CTX_free(bctx); BN_free(y); BN_free(v);
		msyslog(LOG_ERR, "crypto_gq: %s",
		    ERR_error_string(ERR_get_error(), NULL));
		return (XEVNT_ERR);
	}
	DSA_SIG_get0(sdsa, &r, &s);
	if (peer->grpkey == NULL) {
		msyslog(LOG_NOTICE, "crypto_gq: missing group key");
		return (XEVNT_ID);
	}
	BN_mod_exp(v, peer->grpkey, peer->iffval, n, bctx);
	BN_mod_exp(y, r, e, n, bctx); 
	BN_mod_mul(y, v, y, n, bctx);	
	bighash(y, y);
	temp = BN_cmp(y, s);
	BN_CTX_free(bctx); BN_free(y); BN_free(v);
	BN_free(peer->iffval);
	peer->iffval = NULL;
	DSA_SIG_free(sdsa);
	if (temp == 0)
		return (XEVNT_OK);
	msyslog(LOG_NOTICE, "crypto_gq: identity not verified");
	return (XEVNT_ID);
}
int crypto_gq ( struct exten * ep , struct peer * peer ) { RSA * rsa ; BN_CTX * bctx ; DSA_SIG * sdsa ; BIGNUM * y , * v ; const u_char * ptr ; long len ; u_int temp ; const BIGNUM * n , * e ; const BIGNUM * r , * s ; if ( peer -> ident_pkey == NULL ) { msyslog ( LOG_NOTICE , " " ) ; return ( XEVNT_ID ) ; } if ( ntohl ( ep -> fstamp ) < peer -> ident_pkey -> fstamp ) { msyslog ( LOG_NOTICE , " " , ntohl ( ep -> fstamp ) ) ; return ( XEVNT_FSP ) ; } if ( ( rsa = EVP_PKEY_get0_RSA ( peer -> ident_pkey -> pkey ) ) == NULL ) { msyslog ( LOG_NOTICE , " " ) ; return ( XEVNT_PUB ) ; } RSA_get0_key ( rsa , & n , NULL , & e ) ; if ( peer -> iffval == NULL ) { msyslog ( LOG_NOTICE , " " ) ; return ( XEVNT_ID ) ; } bctx = BN_CTX_new ( ) ; y = BN_new ( ) ; v = BN_new ( ) ; len = ntohl ( ep -> vallen ) ; ptr = ( u_char * ) ep -> pkt ; if ( ( sdsa = d2i_DSA_SIG ( NULL , & ptr , len ) ) == NULL ) { BN_CTX_free ( bctx ) ; BN_free ( y ) ; BN_free ( v ) ; msyslog ( LOG_ERR , " " , ERR_error_string ( ERR_get_error ( ) , NULL ) ) ; return ( XEVNT_ERR ) ; } DSA_SIG_get0 ( sdsa , & r , & s ) ; if ( peer -> grpkey == NULL ) { msyslog ( LOG_NOTICE , " " ) ; return ( XEVNT_ID ) ; } BN_mod_exp ( v , peer -> grpkey , peer -> iffval , n , bctx ) ; BN_mod_exp ( y , r , e , n , bctx ) ; BN_mod_mul ( y , v , y , n , bctx ) ; bighash ( y , y ) ; temp = BN_cmp ( y , s ) ; BN_CTX_free ( bctx ) ; BN_free ( y ) ; BN_free ( v ) ; BN_free ( peer -> iffval ) ; peer -> iffval = NULL ; DSA_SIG_free ( sdsa ) ; if ( temp == 0 ) return ( XEVNT_OK ) ; msyslog ( LOG_NOTICE , " " ) ; return ( XEVNT_ID ) ; }
crypto_gq - verify Bob's response to Alice's challenge
 Returns
 XEVNT_OK     success
 XEVNT_ERR    protocol error
 XEVNT_FSP    bad filestamp
 XEVNT_ID     bad or missing group keys
 XEVNT_PUB    bad or missing public key
crypto_gq - verify Bob ' s response to Alice ' s challenge Returns XEVNT_OK success XEVNT_ERR protocol error XEVNT_FSP bad filestamp XEVNT_ID bad or missing group keys XEVNT_PUB bad or missing public key
/* extension pointer */ /* peer structure pointer */ /* GQ parameters */ /* BIGNUM context */ /* RSA signature context fake */ /*
	 * If the GQ parameters are not valid or no challenge was sent,
	 * something awful happened or we are being tormented. Note that
	 * the filestamp on the local key file can be greater than on
	 * the remote parameter file if the keys have been refreshed.
	 */ /*
	 * Extract the y = k u^r and hash(x = k^b) values from the
	 * response.
	 */ /*
	 * Compute v^r y^b mod n.
	 */ /* v^r mod n */ /* y^b mod n */ /* v^r y^b mod n */ /*
	 * Verify the hash of the result matches hash(x).
	 */