@@ -89,6 +89,58 @@ def printprotintelligenceintro():
8989
9090
9191
92+
93+ # Retrieve the timestamp of created email addreses
94+
95+ def extract_timestamp (mail , source_code ):
96+
97+ try :
98+ timestamp = re .sub (':' , '' , re .search (':[0-9]{10}::' , source_code .text ).group (0 ))
99+ creation_date = datetime .fromtimestamp (int (timestamp ))
100+
101+ return creation_date
102+
103+ except AttributeError :
104+ return None
105+
106+
107+
108+ # Perform the API request
109+
110+ def make_api_request (mail ):
111+ try :
112+ request = requests .get ("https://account.proton.me/api/users/available" ,
113+ headers = {
114+ "x-pm-appversion" :"web-account@5.0.11.11" ,
115+ "x-pm-locale" :"en_US"
116+ },
117+ params = {
118+ "Name" :mail ,
119+ "ParseDomain" :"1"
120+ })
121+
122+ #Return code 429 = API limit exceeded
123+ if (request .status_code == 409 ):
124+ source_code = requests .get ('https://api.protonmail.ch/pks/lookup?op=index&search=' + mail )
125+ creation_date = extract_timestamp (mail , source_code )
126+
127+ print ("\033 [1m\n \n ProtonMail Account is VALID! Creation date: " + str (creation_date ) + " \033 [0m\U0001F4A5 " )
128+
129+ return True
130+
131+ elif (request .status_code == 429 ):
132+ print ("\u001b [31m\n \n API requests limit exceeded..." )
133+
134+ else :
135+ print ("\u001b [31m\n \n ProtonMail account is NOT VALID" )
136+
137+ return False
138+
139+ except :
140+ print ("Error when requesting the API" )
141+ return False
142+
143+
92144# ProtonMail account validity check
93145
94146def protonmailaccountcheck ():
@@ -111,17 +163,7 @@ def protonmailaccountcheck():
111163 print ("\u001b [31m\n \n ProtonMail user does not exist\u001b [32m" )
112164 invalidEmail = True
113165
114- requestProton = requests .get ('https://api.protonmail.ch/pks/lookup?op=index&search=' + str (mail ))
115- bodyResponse = requestProton .text
116-
117- protonmailaccountdoesnotexist = "info:1:0"
118- protonmailaccountexists = "info:1:1"
119-
120- if protonmailaccountdoesnotexist in bodyResponse :
121- print ("\u001b [31m\n \n ProtonMail account is NOT VALID" )
122-
123- if protonmailaccountexists in bodyResponse :
124- print ("\033 [1m\n \n ProtonMail Account is VALID!\033 [0m\U0001F4A5 " )
166+ make_api_request (mail )
125167
126168
127169
@@ -186,7 +228,6 @@ def darkwebbrowser():
186228 webbrowser .open ("https://ahmia.fi/search/?q=%s" % query )
187229
188230
189-
190231# Search results displayed within the terminal
191232
192233def darkwebterminal ():
@@ -208,9 +249,6 @@ def darkwebterminal():
208249 print (a_href ["href" ])
209250
210251
211-
212-
213-
214252# Get ProtonMail User PGP Key
215253
216254def pgpkeyinformation ():
@@ -240,6 +278,20 @@ def pgpkeydirectdownload():
240278 webbrowser .open ("https://api.protonmail.ch/pks/lookup?op=get&search=" + query )
241279
242280
281+ def extract_key (source_code ):
282+ """
283+ Extract the key type and length of the email address
284+ """
285+
286+ regex = ':[0-9]{2,4}:(.*)::'
287+
288+ try :
289+ key = re .search (regex , source_code .text ).group (0 ).split (":" )[1 ]
290+ return key
291+ except AttributeError :
292+ return None
293+
294+
243295def pgpkeyview ():
244296 """
245297 View PGP Key in Terminal
@@ -261,38 +313,20 @@ def pgpkeyview():
261313 print ("\u001b [31m\n \n Protonmail user does not exist\u001b [32m" )
262314 invalidEmail = True
263315
264- requestProton = requests .get ('https://api.protonmail.ch/pks/lookup?op=index&search=' + str (mail ))
265- bodyResponse = requestProton .text
266-
267- protonmailaccountdoesnotexist = "info:1:0"
268- protonmailaccountexists = "info:1:1"
316+ if (make_api_request (mail )):
269317
270- if protonmailaccountdoesnotexist in bodyResponse :
271- print ( " \u001b [31m \n ProtonMail account is NOT VALID" )
318+ #Refractor this by removing all of this and use the function extract_timestamp(email) instead
319+ source_code = requests . get ( 'https://api.protonmail.ch/pks/lookup?op=index&search=' + mail )
272320
273- if protonmailaccountexists in bodyResponse :
274- print ( " \033 [1m \n ProtonMail account PGP Key Found! \n \033 [0m \u001b [32m" )
321+ timestamp = extract_timestamp ( mail , source_code )
322+ key = extract_key ( source_code )
275323
276- regexPattern1 = "2048:(.*)::" # RSA 2048-bit (Older but faster)
277- regexPattern2 = "4096:(.*)::" # RSA 4096-bit (Secure but slow)
278- regexPattern3 = "22::(.*)::" # X25519 (Modern, fastest, secure)
279- try :
280- timestamp = int (re .search (regexPattern1 , bodyResponse ).group (1 ))
281- dtObject = datetime .fromtimestamp (timestamp )
282- print ("PGP Key Date and Creation Time:" , dtObject )
283- print ("Encryption Standard : RSA 2048-bit" )
284- except :
285- try :
286- timestamp = int (re .search (regexPattern2 , bodyResponse ).group (1 ))
287- dtObject = datetime .fromtimestamp (timestamp )
288- print ("PGP Key Date and Creation Time:" , dtObject )
289- print ("Encryption Standard : RSA 4096-bit " )
290- except :
291- timestamp = int (re .search (regexPattern3 , bodyResponse ).group (1 ))
292- dtObject = datetime .fromtimestamp (timestamp )
293- print ("PGP Key Date and Creation Time:" , dtObject )
294- print ("Encryption Standard : ECC Curve25519 " )
324+ print ("PGP Key Date and Creation Time:" , str (timestamp ))
295325
326+ if (key != "22" ):
327+ print ("Encryption Standard : RSA " + key + "-bit" )
328+ else :
329+ print ("Encryption Standard : ECC Curve25519" )
296330
297331 # Get the USER PGP Key
298332 invalidResponse = True
0 commit comments