+
+ while( ( i_read = stream_Read( p_stream, p_buffer, 1 << 10 ) ) &&
+ !intf_ProgressIsCancelled( p_udt, i_progress ) )
+ {
+ if( fwrite( p_buffer, i_read, 1, p_file ) < 1 )
+ {
+ msg_Err( p_udt, "Failed to write into %s", psz_destfile );
+ break;
+ }
+
+ l_downloaded += i_read;
+ psz_downloaded = size_str( l_downloaded );
+ f_progress = 100.0*(float)l_downloaded/(float)l_size;
+
+ if( asprintf( &psz_status, "%s\nDonwloading... %s/%s %.1f%% done",
+ p_update->release.psz_url, psz_downloaded, psz_size,
+ f_progress ) != -1 )
+ {
+ intf_ProgressUpdate( p_udt, i_progress, psz_status, f_progress, 0 );
+ free( psz_status );
+ }
+ free( psz_downloaded );
+ }
+
+ /* Finish the progress bar or delete the file if the user had canceled */
+ fclose( p_file );
+ p_file = NULL;
+
+ if( !intf_ProgressIsCancelled( p_udt, i_progress ) )
+ {
+ if( asprintf( &psz_status, "%s\nDone %s (100.0%%)",
+ p_update->release.psz_url, psz_size ) != -1 )
+ {
+ intf_ProgressUpdate( p_udt, i_progress, psz_status, 100.0, 0 );
+ free( psz_status );
+ }
+ }
+ else
+ {
+ utf8_unlink( psz_destfile );
+ goto end;
+ }
+
+ signature_packet_v3_t sign;
+ if( download_signature( VLC_OBJECT( p_udt ), &sign,
+ p_update->release.psz_url ) != VLC_SUCCESS )
+ {
+ utf8_unlink( psz_destfile );
+
+ intf_UserFatal( p_udt, VLC_TRUE, _("File can not be verified"),
+ _("It was not possible to download a cryptographic signature for "
+ "downloaded file \"%s\", and so VLC deleted it."),
+ psz_destfile );
+ msg_Err( p_udt, "Couldn't download signature of downloaded file" );
+ goto end;
+ }
+
+ if( memcmp( sign.issuer_longid, p_update->p_pkey->longid, 8 ) )
+ {
+ utf8_unlink( psz_destfile );
+ msg_Err( p_udt, "Invalid signature issuer" );
+ intf_UserFatal( p_udt, VLC_TRUE, _("Invalid signature"),
+ _("The cryptographic signature for downloaded file \"%s\" was "
+ "invalid and couldn't be used to securely verify it, and so "
+ "VLC deleted it."),
+ psz_destfile );
+ goto end;
+ }
+
+ if( sign.type != BINARY_SIGNATURE )
+ {
+ utf8_unlink( psz_destfile );
+ msg_Err( p_udt, "Invalid signature type" );
+ intf_UserFatal( p_udt, VLC_TRUE, _("Invalid signature"),
+ _("The cryptographic signature for downloaded file \"%s\" was "
+ "invalid and couldn't be used to securely verify it, and so "
+ "VLC deleted it."),
+ psz_destfile );
+ goto end;
+ }
+
+ uint8_t *p_hash = hash_sha1_from_file( psz_destfile, &sign );
+ if( !p_hash )
+ {
+ msg_Err( p_udt, "Unable to hash %s", psz_destfile );
+ utf8_unlink( psz_destfile );
+ intf_UserFatal( p_udt, VLC_TRUE, _("File not verifiable"),
+ _("It was not possible to securely verify downloaded file \"%s\", "
+ "and so VLC deleted it."),
+ psz_destfile );
+
+ goto end;
+ }
+
+ if( p_hash[0] != sign.hash_verification[0] ||
+ p_hash[1] != sign.hash_verification[1] )
+ {
+ utf8_unlink( psz_destfile );
+ intf_UserFatal( p_udt, VLC_TRUE, _("File corrupted"),
+ _("Downloaded file \"%s\" was corrupted, and so VLC deleted it."),
+ psz_destfile );
+ msg_Err( p_udt, "Bad SHA1 hash for %s", psz_destfile );
+ free( p_hash );
+ goto end;
+ }
+
+ if( verify_signature( sign.r, sign.s, &p_update->p_pkey->key, p_hash )
+ != VLC_SUCCESS )
+ {
+ utf8_unlink( psz_destfile );
+ intf_UserFatal( p_udt, VLC_TRUE, _("File corrupted"),
+ _("Downloaded file \"%s\" was corrupted, and so VLC deleted it."),
+ psz_destfile );
+ msg_Err( p_udt, "BAD SIGNATURE for %s", psz_destfile );
+ free( p_hash );
+ goto end;
+ }
+
+ msg_Info( p_udt, "%s authenticated", psz_destfile );
+ free( p_hash );
+
+end:
+ if( p_stream )
+ stream_Delete( p_stream );
+ if( p_file )
+ fclose( p_file );
+ free( psz_destdir );
+ free( psz_destfile );
+ free( p_buffer );
+ free( psz_size );
+
+ vlc_object_release( p_udt );