|  | @@ -1076,6 +1076,44 @@ static char * http_basic_auth ( struct http_request *http ) {
 | 
		
	
		
			
			| 1076 | 1076 |  	return auth;
 | 
		
	
		
			
			| 1077 | 1077 |  }
 | 
		
	
		
			
			| 1078 | 1078 |  
 | 
		
	
		
			
			|  | 1079 | +/**
 | 
		
	
		
			
			|  | 1080 | + * Initialise HTTP digest
 | 
		
	
		
			
			|  | 1081 | + *
 | 
		
	
		
			
			|  | 1082 | + * @v ctx		Digest context
 | 
		
	
		
			
			|  | 1083 | + * @v string		Initial string
 | 
		
	
		
			
			|  | 1084 | + */
 | 
		
	
		
			
			|  | 1085 | +static void http_digest_init ( struct md5_context *ctx ) {
 | 
		
	
		
			
			|  | 1086 | +
 | 
		
	
		
			
			|  | 1087 | +	digest_init ( &md5_algorithm, ctx );
 | 
		
	
		
			
			|  | 1088 | +}
 | 
		
	
		
			
			|  | 1089 | +
 | 
		
	
		
			
			|  | 1090 | +/**
 | 
		
	
		
			
			|  | 1091 | + * Update HTTP digest with new data
 | 
		
	
		
			
			|  | 1092 | + *
 | 
		
	
		
			
			|  | 1093 | + * @v ctx		Digest context
 | 
		
	
		
			
			|  | 1094 | + * @v string		String to append
 | 
		
	
		
			
			|  | 1095 | + */
 | 
		
	
		
			
			|  | 1096 | +static void http_digest_update ( struct md5_context *ctx, const char *string ) {
 | 
		
	
		
			
			|  | 1097 | +	static const char colon = ':';
 | 
		
	
		
			
			|  | 1098 | +
 | 
		
	
		
			
			|  | 1099 | +	if ( ctx->len )
 | 
		
	
		
			
			|  | 1100 | +		digest_update ( &md5_algorithm, ctx, &colon, sizeof ( colon ) );
 | 
		
	
		
			
			|  | 1101 | +	digest_update ( &md5_algorithm, ctx, string, strlen ( string ) );
 | 
		
	
		
			
			|  | 1102 | +}
 | 
		
	
		
			
			|  | 1103 | +
 | 
		
	
		
			
			|  | 1104 | +/**
 | 
		
	
		
			
			|  | 1105 | + * Finalise HTTP digest
 | 
		
	
		
			
			|  | 1106 | + *
 | 
		
	
		
			
			|  | 1107 | + * @v ctx		Digest context
 | 
		
	
		
			
			|  | 1108 | + * @v out		Buffer for digest output
 | 
		
	
		
			
			|  | 1109 | + */
 | 
		
	
		
			
			|  | 1110 | +static void http_digest_final ( struct md5_context *ctx, char *out ) {
 | 
		
	
		
			
			|  | 1111 | +	uint8_t digest[MD5_DIGEST_SIZE];
 | 
		
	
		
			
			|  | 1112 | +
 | 
		
	
		
			
			|  | 1113 | +	digest_final ( &md5_algorithm, ctx, digest );
 | 
		
	
		
			
			|  | 1114 | +	base16_encode ( digest, sizeof ( digest ), out );
 | 
		
	
		
			
			|  | 1115 | +}
 | 
		
	
		
			
			|  | 1116 | +
 | 
		
	
		
			
			| 1079 | 1117 |  /**
 | 
		
	
		
			
			| 1080 | 1118 |   * Generate HTTP Digest authorisation string
 | 
		
	
		
			
			| 1081 | 1119 |   *
 | 
		
	
	
		
			
			|  | @@ -1095,12 +1133,10 @@ static char * http_digest_auth ( struct http_request *http,
 | 
		
	
		
			
			| 1095 | 1133 |  	const char *realm = http->auth_realm;
 | 
		
	
		
			
			| 1096 | 1134 |  	const char *nonce = http->auth_nonce;
 | 
		
	
		
			
			| 1097 | 1135 |  	const char *opaque = http->auth_opaque;
 | 
		
	
		
			
			| 1098 |  | -	static const char colon = ':';
 | 
		
	
		
			
			| 1099 |  | -	uint8_t ctx[MD5_CTX_SIZE];
 | 
		
	
		
			
			| 1100 |  | -	uint8_t digest[MD5_DIGEST_SIZE];
 | 
		
	
		
			
			| 1101 |  | -	char ha1[ base16_encoded_len ( sizeof ( digest ) ) + 1 /* NUL */ ];
 | 
		
	
		
			
			| 1102 |  | -	char ha2[ base16_encoded_len ( sizeof ( digest ) ) + 1 /* NUL */ ];
 | 
		
	
		
			
			| 1103 |  | -	char response[ base16_encoded_len ( sizeof ( digest ) ) + 1 /* NUL */ ];
 | 
		
	
		
			
			|  | 1136 | +	struct md5_context ctx;
 | 
		
	
		
			
			|  | 1137 | +	char ha1[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
 | 
		
	
		
			
			|  | 1138 | +	char ha2[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
 | 
		
	
		
			
			|  | 1139 | +	char response[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
 | 
		
	
		
			
			| 1104 | 1140 |  	char *auth;
 | 
		
	
		
			
			| 1105 | 1141 |  	int len;
 | 
		
	
		
			
			| 1106 | 1142 |  
 | 
		
	
	
		
			
			|  | @@ -1110,32 +1146,24 @@ static char * http_digest_auth ( struct http_request *http,
 | 
		
	
		
			
			| 1110 | 1146 |  	assert ( nonce != NULL );
 | 
		
	
		
			
			| 1111 | 1147 |  
 | 
		
	
		
			
			| 1112 | 1148 |  	/* Generate HA1 */
 | 
		
	
		
			
			| 1113 |  | -	digest_init ( &md5_algorithm, ctx );
 | 
		
	
		
			
			| 1114 |  | -	digest_update ( &md5_algorithm, ctx, user, strlen ( user ) );
 | 
		
	
		
			
			| 1115 |  | -	digest_update ( &md5_algorithm, ctx, &colon, sizeof ( colon ) );
 | 
		
	
		
			
			| 1116 |  | -	digest_update ( &md5_algorithm, ctx, realm, strlen ( realm ) );
 | 
		
	
		
			
			| 1117 |  | -	digest_update ( &md5_algorithm, ctx, &colon, sizeof ( colon ) );
 | 
		
	
		
			
			| 1118 |  | -	digest_update ( &md5_algorithm, ctx, password, strlen ( password ) );
 | 
		
	
		
			
			| 1119 |  | -	digest_final ( &md5_algorithm, ctx, digest );
 | 
		
	
		
			
			| 1120 |  | -	base16_encode ( digest, sizeof ( digest ), ha1 );
 | 
		
	
		
			
			|  | 1149 | +	http_digest_init ( &ctx );
 | 
		
	
		
			
			|  | 1150 | +	http_digest_update ( &ctx, user );
 | 
		
	
		
			
			|  | 1151 | +	http_digest_update ( &ctx, realm );
 | 
		
	
		
			
			|  | 1152 | +	http_digest_update ( &ctx, password );
 | 
		
	
		
			
			|  | 1153 | +	http_digest_final ( &ctx, ha1 );
 | 
		
	
		
			
			| 1121 | 1154 |  
 | 
		
	
		
			
			| 1122 | 1155 |  	/* Generate HA2 */
 | 
		
	
		
			
			| 1123 |  | -	digest_init ( &md5_algorithm, ctx );
 | 
		
	
		
			
			| 1124 |  | -	digest_update ( &md5_algorithm, ctx, method, strlen ( method ) );
 | 
		
	
		
			
			| 1125 |  | -	digest_update ( &md5_algorithm, ctx, &colon, sizeof ( colon ) );
 | 
		
	
		
			
			| 1126 |  | -	digest_update ( &md5_algorithm, ctx, uri, strlen ( uri ) );
 | 
		
	
		
			
			| 1127 |  | -	digest_final ( &md5_algorithm, ctx, digest );
 | 
		
	
		
			
			| 1128 |  | -	base16_encode ( digest, sizeof ( digest ), ha2 );
 | 
		
	
		
			
			|  | 1156 | +	http_digest_init ( &ctx );
 | 
		
	
		
			
			|  | 1157 | +	http_digest_update ( &ctx, method );
 | 
		
	
		
			
			|  | 1158 | +	http_digest_update ( &ctx, uri );
 | 
		
	
		
			
			|  | 1159 | +	http_digest_final ( &ctx, ha2 );
 | 
		
	
		
			
			| 1129 | 1160 |  
 | 
		
	
		
			
			| 1130 | 1161 |  	/* Generate response */
 | 
		
	
		
			
			| 1131 |  | -	digest_init ( &md5_algorithm, ctx );
 | 
		
	
		
			
			| 1132 |  | -	digest_update ( &md5_algorithm, ctx, ha1, strlen ( ha1 ) );
 | 
		
	
		
			
			| 1133 |  | -	digest_update ( &md5_algorithm, ctx, &colon, sizeof ( colon ) );
 | 
		
	
		
			
			| 1134 |  | -	digest_update ( &md5_algorithm, ctx, nonce, strlen ( nonce ) );
 | 
		
	
		
			
			| 1135 |  | -	digest_update ( &md5_algorithm, ctx, &colon, sizeof ( colon ) );
 | 
		
	
		
			
			| 1136 |  | -	digest_update ( &md5_algorithm, ctx, ha2, strlen ( ha2 ) );
 | 
		
	
		
			
			| 1137 |  | -	digest_final ( &md5_algorithm, ctx, digest );
 | 
		
	
		
			
			| 1138 |  | -	base16_encode ( digest, sizeof ( digest ), response );
 | 
		
	
		
			
			|  | 1162 | +	http_digest_init ( &ctx );
 | 
		
	
		
			
			|  | 1163 | +	http_digest_update ( &ctx, ha1 );
 | 
		
	
		
			
			|  | 1164 | +	http_digest_update ( &ctx, nonce );
 | 
		
	
		
			
			|  | 1165 | +	http_digest_update ( &ctx, ha2 );
 | 
		
	
		
			
			|  | 1166 | +	http_digest_final ( &ctx, response );
 | 
		
	
		
			
			| 1139 | 1167 |  
 | 
		
	
		
			
			| 1140 | 1168 |  	/* Generate the authorisation string */
 | 
		
	
		
			
			| 1141 | 1169 |  	len = asprintf ( &auth, "Authorization: Digest username=\"%s\", "
 |