|
|
@ -19,30 +19,37 @@ |
|
|
|
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
|
|
|
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
|
|
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
|
|
"""PKCE utility functions for code verifier and code challenge generation.""" |
|
|
|
|
|
|
|
import base64 |
|
|
|
import hashlib |
|
|
|
import os |
|
|
|
from typing import Tuple |
|
|
|
|
|
|
|
|
|
|
|
def generate_code_verifier(length: int = 128) -> str: |
|
|
|
""" |
|
|
|
Generates a high-entropy cryptographic random string for PKCE code_verifier. |
|
|
|
Generate a high-entropy cryptographic random string for PKCE code_verifier. |
|
|
|
|
|
|
|
RFC 7636 recommends a length between 43 and 128 characters. |
|
|
|
""" |
|
|
|
return base64.urlsafe_b64encode(os.urandom(length)).rstrip(b"=").decode("utf-8")[:length] |
|
|
|
|
|
|
|
def generate_code_challenge(code_verifier: str, method: str = "S256") -> Tuple[str, str]: |
|
|
|
|
|
|
|
def generate_code_challenge(code_verifier: str, method: str = "S256") -> tuple[str, str]: |
|
|
|
""" |
|
|
|
Generates a code_challenge from the code_verifier using the specified method. |
|
|
|
Supported methods: "S256" (default), "plain" |
|
|
|
Returns (code_challenge, code_challenge_method) |
|
|
|
Generate a code_challenge from the code_verifier using the specified method. |
|
|
|
|
|
|
|
Supported methods: "S256" (default), "plain". |
|
|
|
Returns (code_challenge, code_challenge_method). |
|
|
|
""" |
|
|
|
if method == "S256": |
|
|
|
code_challenge = base64.urlsafe_b64encode( |
|
|
|
hashlib.sha256(code_verifier.encode("utf-8")).digest() |
|
|
|
).rstrip(b"=").decode("utf-8") |
|
|
|
code_challenge = ( |
|
|
|
base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode("utf-8")).digest()) |
|
|
|
.rstrip(b"=") |
|
|
|
.decode("utf-8") |
|
|
|
) |
|
|
|
return code_challenge, "S256" |
|
|
|
if method == "plain": |
|
|
|
return code_verifier, "plain" |
|
|
|
raise ValueError(f"Unsupported PKCE method: {method}") |
|
|
|
error_msg = f"Unsupported PKCE method: {method}" |
|
|
|
raise ValueError(error_msg) |