コード例 #1
0
ファイル: base16.c プロジェクト: 3a9LL/panda
/**
 * Base16-encode data
 *
 * @v raw		Raw data
 * @v len		Length of raw data
 * @v encoded		Buffer for encoded string
 *
 * The buffer must be the correct length for the encoded string.  Use
 * something like
 *
 *     char buf[ base16_encoded_len ( len ) + 1 ];
 *
 * (the +1 is for the terminating NUL) to provide a buffer of the
 * correct size.
 */
void base16_encode ( const uint8_t *raw, size_t len, char *encoded ) {
	const uint8_t *raw_bytes = raw;
	char *encoded_bytes = encoded;
	size_t remaining = len;

	for ( ; remaining-- ; encoded_bytes += 2 ) {
		sprintf ( encoded_bytes, "%02x", *(raw_bytes++) );
	}

	DBG ( "Base16-encoded to \"%s\":\n", encoded );
	DBG_HDA ( 0, raw, len );
	assert ( strlen ( encoded ) == base16_encoded_len ( len ) );
}
コード例 #2
0
ファイル: certmgmt.c プロジェクト: andrewrothstein/ipxe
/**
 * Display status of a certificate
 *
 * @v cert		X.509 certificate
 */
void certstat ( struct x509_certificate *cert ) {
	struct digest_algorithm *digest = &sha1_algorithm;
	uint8_t fingerprint[ digest->digestsize ];
	char buf[ base16_encoded_len ( sizeof ( fingerprint ) ) + 1 /* NUL */ ];

	/* Generate fingerprint */
	x509_fingerprint ( cert, digest, fingerprint );
	base16_encode ( fingerprint, sizeof ( fingerprint ),
			buf, sizeof ( buf ) );

	/* Print certificate status */
	printf ( "%s : %s", x509_name ( cert ), buf );
	if ( cert->flags & X509_FL_PERMANENT )
		printf ( " [PERMANENT]" );
	if ( cert->flags & X509_FL_EXPLICIT )
		printf ( " [EXPLICIT]" );
	if ( x509_is_valid ( cert ) )
		printf ( " [VALIDATED]" );
	printf ( "\n" );
}
コード例 #3
0
/**
 * Perform HTTP Digest authentication
 *
 * @v http		HTTP transaction
 * @ret rc		Return status code
 */
static int http_digest_authenticate ( struct http_transaction *http ) {
	struct http_request_auth *req = &http->request.auth;
	struct http_response_auth *rsp = &http->response.auth;
	char ha1[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
	char ha2[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
	static const char md5sess[] = "MD5-sess";
	static const char md5[] = "MD5";
	struct md5_context ctx;

	/* Check for required response parameters */
	if ( ! rsp->realm ) {
		DBGC ( http, "HTTP %p has no realm for Digest authentication\n",
		       http );
		return -EINVAL;
	}
	if ( ! rsp->nonce ) {
		DBGC ( http, "HTTP %p has no nonce for Digest authentication\n",
		       http );
		return -EINVAL;
	}

	/* Record username and password */
	if ( ! http->uri->user ) {
		DBGC ( http, "HTTP %p has no username for Digest "
		       "authentication\n", http );
		return -EACCES_USERNAME;
	}
	req->username = http->uri->user;
	req->password = ( http->uri->password ? http->uri->password : "" );

	/* Handle quality of protection */
	if ( rsp->qop ) {

		/* Use "auth" in subsequent request */
		req->qop = "auth";

		/* Generate a client nonce */
		snprintf ( req->cnonce, sizeof ( req->cnonce ),
			   "%08lx", random() );

		/* Determine algorithm */
		req->algorithm = md5;
		if ( rsp->algorithm &&
		     ( strcasecmp ( rsp->algorithm, md5sess ) == 0 ) ) {
			req->algorithm = md5sess;
		}
	}

	/* Generate HA1 */
	http_digest_init ( &ctx );
	http_digest_update ( &ctx, req->username );
	http_digest_update ( &ctx, rsp->realm );
	http_digest_update ( &ctx, req->password );
	http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
	if ( req->algorithm == md5sess ) {
		http_digest_init ( &ctx );
		http_digest_update ( &ctx, ha1 );
		http_digest_update ( &ctx, rsp->nonce );
		http_digest_update ( &ctx, req->cnonce );
		http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
	}

	/* Generate HA2 */
	http_digest_init ( &ctx );
	http_digest_update ( &ctx, http->request.method->name );
	http_digest_update ( &ctx, http->request.uri );
	http_digest_final ( &ctx, ha2, sizeof ( ha2 ) );

	/* Generate response */
	http_digest_init ( &ctx );
	http_digest_update ( &ctx, ha1 );
	http_digest_update ( &ctx, rsp->nonce );
	if ( req->qop ) {
		http_digest_update ( &ctx, HTTP_DIGEST_NC );
		http_digest_update ( &ctx, req->cnonce );
		http_digest_update ( &ctx, req->qop );
	}
	http_digest_update ( &ctx, ha2 );
	http_digest_final ( &ctx, req->response, sizeof ( req->response ) );

	return 0;
}