@echo off

rem  ********************************************************************************
rem  *                 Read Me Read Me Read Me Read Me Read Me                      *
rem  *                 =======================================                      *
rem  *                                                                              *
rem  *  Dependencies : xxd, grep, tail, sed, cmdcolor and Base64 plus dlls          *
rem  *  Copy this file to a directory, say C:\private\ism2pssh\                     * 
rem  *  Place all dependencies in this same directory.                              *
rem  *  In same directory create two subdirectories called tmp and pssh             *
rem  *  ism2pssh.cmd will place the captured pssh into the pssh folder              *
rem  *  Open Cmd window and run this cmd file.                                      *
rem  *                                                                              *
rem  ********************************************************************************

title ism2pssh by Jack_666

color 1f

echo+
echo+
echo \033[30;107m   **************  PSSH Capture from ism manifest \033[92;107m(by Jack_666)\033[30;107m **************   \033[0m  | cmdcolor.exe
echo+
echo+

set err_code=0
set url=blank
type NUL >  tmp\_url.txt 

echo \033[97;104mPlease enter the URL of the ism manifest :\033[0m  | cmdcolor.exe
set /p url= 

echo+
echo \033[97;43mProcessing\033[0m  | cmdcolor.exe
echo | set /p dummyName=..

:: Error checking the URL entry

if "%url%" EQU "blank" set err_code=1 & goto display_error
echo | set /p dummyName=..

echo %url% > tmp\_url.txt
FOR %%? IN (tmp\_url.txt) DO ( SET /A strlength=%%~z? - 3 )
if %strlength% LSS 25 set err_code=2 & goto display_error
echo | set /p dummyName=..

grep -c https tmp\_url.txt > tmp\_temp_01.txt
set /p err_check=<tmp\_temp_01.txt
if %err_check% LSS 1 set err_code=4 & goto display_error
echo | set /p dummyName=..

grep -c ism/manifest tmp\_url.txt > tmp\_temp_01.txt
set /p err_check=<tmp\_temp_01.txt
if %err_check% LSS 1 set err_code=8 & goto display_error
echo | set /p dummyName=..

curl -Isf %url% | grep -c "HTTP/1.1 200 OK" > tmp\_temp_01.txt
set /p err_check=<tmp\_temp_01.txt
if %err_check% LSS 1 set err_code=16 & goto display_error
echo | set /p dummyName=..

curl -s %url% -o tmp\ism.txt
echo | set /p dummyName=..

grep -c ProtectionHeader tmp\ism.txt > tmp\_temp_01.txt
set /p err_check=<tmp\_temp_01.txt
if %err_check% LSS 1 set err_code=32 & goto display_error
echo | set /p dummyName=..

grep ProtectionHeader tmp\ism.txt | sed -e "s#<.ProtectionHeader>##" | sed -e "s#^.*>##" > tmp\_temp_01.txt

:: Decode the Base64 Protection Header and grab kid in base64
Base64 /d  tmp\_temp_01.txt | xxd -l 512  -c 256 | tail -1 | sed -e "s#\.##g" | sed -e "s#^.*<KID>\(.*\)</KID>.*$#\1#" > tmp\_temp_03.txt
echo | set /p dummyName=..

:: The kid is in base64 and stored in tmp\_temp_03.txt
:: We need to determine if any kid was captured
FOR %%? IN (tmp\_temp_03.txt) DO ( SET /A strlength=%%~z? - 1 )
if %strlength% NEQ 24 set err_code=64 & goto display_error
echo | set /p dummyName=..

set /p kid_b64=<tmp\_temp_03.txt

:: Convert the kid to hex (little endian format)
Base64 /d  tmp\_temp_03.txt | xxd -ps > tmp\_temp_05.txt
set /p kid_le=<tmp\_temp_05.txt
echo | set /p dummyName=..

:: convert kid from  little-endian to big-endian
sed -e "s#\(^..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(.*$\)#\4\3\2\1\6\5\8\7\9#" tmp\_temp_05.txt > tmp\_temp_05a.txt 
set /p kid_be=<tmp\_temp_05a.txt
echo | set /p dummyName=..

set pssh=000000327073736800000000edef8ba979d64acea3c827dcd51d21ed000000121210%kid_be%

:: xxd will convert the captured hex values to ascii
echo %pssh% | xxd -r -ps  > tmp\_temp_06.txt

:: Base64 will convert the ascii data to base 64  ... the pssh in base 64
Base64 /e tmp\_temp_06.txt > pssh\pssh.txt

echo+
echo+
echo \033[97;42mpssh (Base64) :\033[0m  | cmdcolor.exe 
type pssh\pssh.txt
echo+

:display_error
if %err_code% EQU 0  goto program_complete
echo+
echo+
if %err_code% EQU 1  echo \033[97;101mError in URL entry ... You forgot to enter the URL.\033[0m  | cmdcolor.exe
if %err_code% EQU 2  echo \033[97;101mError in URL entry ... URL length is too short.\033[0m  | cmdcolor.exe
if %err_code% EQU 4  echo \033[97;101mError in URL entry ... https missing from URL.\033[0m  | cmdcolor.exe
if %err_code% EQU 8  echo \033[97;101mError in URL entry ... URL must contain ism/manifest.\033[0m  | cmdcolor.exe
if %err_code% EQU 16 echo \033[97;101mError in URL entry ... URL is not available on server.\033[0m  | cmdcolor.exe
if %err_code% EQU 32 echo \033[97;101mError in URL entry ... ProtectionHeader not found in Manifest. Unexpected Format.\033[0m  | cmdcolor.exe
if %err_code% EQU 64 echo \033[97;101mError in URL entry ... No KID found in Manifest.\033[0m  | cmdcolor.exe
echo+

:program_complete
echo+
echo \033[97;104mProgram Complete\033[0m  | cmdcolor.exe
echo+
