or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdconfiguration.mdindex.mdmessage-processing.mdutilities.md

utilities.mddocs/

0

# Utilities and Security

1

2

Comprehensive utilities for cryptographic operations, XML processing, URL handling, certificate management, and security validation. These utilities provide the foundational security and processing capabilities that underpin all SAML operations.

3

4

## Capabilities

5

6

### Core SAML Utilities

7

8

Essential utility functions for SAML operations including cryptography, XML processing, URL handling, and time utilities.

9

10

```python { .api }

11

class OneLogin_Saml2_Utils:

12

# Class constants for XPath and time handling

13

RESPONSE_SIGNATURE_XPATH = '/samlp:Response/ds:Signature'

14

ASSERTION_SIGNATURE_XPATH = '/samlp:Response/saml:Assertion/ds:Signature'

15

TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"

16

ALLOWED_CLOCK_DRIFT = 300 # seconds

17

```

18

19

### URL and Parameter Handling

20

21

Secure URL processing and parameter management for SAML redirects and requests.

22

23

```python { .api }

24

@staticmethod

25

def redirect(url: str, parameters: dict = {}, request_data: dict = {}) -> str:

26

"""

27

Execute redirection with validation and parameter encoding.

28

29

Parameters:

30

- url: Target URL for redirection

31

- parameters: Query parameters to append

32

- request_data: HTTP request context

33

34

Returns:

35

Complete redirection URL with encoded parameters

36

"""

37

38

@staticmethod

39

def get_self_url_host(request_data: dict) -> str:

40

"""

41

Get protocol + current host + port.

42

43

Parameters:

44

- request_data: HTTP request information

45

46

Returns:

47

Base URL (e.g., "https://example.com:8443")

48

"""

49

50

@staticmethod

51

def get_self_url_no_query(request_data: dict) -> str:

52

"""

53

Get current URL without query string.

54

55

Parameters:

56

- request_data: HTTP request information

57

58

Returns:

59

URL without query parameters

60

"""

61

62

@staticmethod

63

def normalize_url(url: str) -> str:

64

"""

65

Normalize URL for comparison (lowercase netloc).

66

67

Parameters:

68

- url: URL to normalize

69

70

Returns:

71

Normalized URL string

72

"""

73

74

@staticmethod

75

def escape_url(url: str, lowercase_urlencoding: bool = False) -> str:

76

"""

77

Escape non-safe symbols in URLs.

78

79

Parameters:

80

- url: URL to escape

81

- lowercase_urlencoding: Use lowercase encoding for ADFS compatibility

82

83

Returns:

84

URL-encoded string

85

"""

86

```

87

88

### Base64 and Compression

89

90

Encoding and compression utilities for SAML message processing.

91

92

```python { .api }

93

@staticmethod

94

def b64encode(data: str) -> str:

95

"""

96

Base64 encoding with string compatibility.

97

98

Parameters:

99

- data: Data to encode

100

101

Returns:

102

Base64 encoded string

103

"""

104

105

@staticmethod

106

def b64decode(data: str) -> str:

107

"""

108

Base64 decoding with proper padding.

109

110

Parameters:

111

- data: Base64 encoded data

112

113

Returns:

114

Decoded string

115

"""

116

117

@staticmethod

118

def deflate_and_base64_encode(value: str) -> str:

119

"""

120

Zlib deflate and base64 encode (for HTTP-Redirect binding).

121

122

Parameters:

123

- value: String to compress and encode

124

125

Returns:

126

Deflated and base64 encoded string

127

"""

128

129

@staticmethod

130

def decode_base64_and_inflate(value: str, ignore_zip: bool = False) -> str:

131

"""

132

Base64 decode and zlib inflate (RFC1951).

133

134

Parameters:

135

- value: Encoded and compressed string

136

- ignore_zip: Skip inflation if True

137

138

Returns:

139

Decoded and inflated string

140

"""

141

```

142

143

### Certificate and Key Management

144

145

X.509 certificate handling and cryptographic key management for SAML security operations.

146

147

```python { .api }

148

@staticmethod

149

def format_cert(cert: str, heads: bool = True) -> str:

150

"""

151

Format X.509 certificate with optional headers/footers.

152

153

Parameters:

154

- cert: Certificate string or PEM data

155

- heads: Whether to include BEGIN/END CERTIFICATE headers

156

157

Returns:

158

Properly formatted certificate string

159

"""

160

161

@staticmethod

162

def format_private_key(key: str, heads: bool = True) -> str:

163

"""

164

Format private key (RSA or PKCS#8) with headers.

165

166

Parameters:

167

- key: Private key string or PEM data

168

- heads: Whether to include BEGIN/END headers

169

170

Returns:

171

Properly formatted private key string

172

"""

173

174

@staticmethod

175

def calculate_x509_fingerprint(x509_cert: str, alg: str = 'sha1') -> str:

176

"""

177

Calculate certificate fingerprint.

178

179

Parameters:

180

- x509_cert: X.509 certificate string

181

- alg: Hash algorithm (sha1, sha256, sha384, sha512)

182

183

Returns:

184

Lowercase fingerprint string without colons

185

"""

186

187

@staticmethod

188

def format_finger_print(fingerprint: str) -> str:

189

"""

190

Format fingerprint by removing colons and converting to lowercase.

191

192

Parameters:

193

- fingerprint: Fingerprint with or without colons

194

195

Returns:

196

Formatted fingerprint string

197

"""

198

```

199

200

### Digital Signatures

201

202

XML digital signature creation and validation with comprehensive security checks.

203

204

```python { .api }

205

@staticmethod

206

def add_sign(xml: str, key: str, cert: str, debug: bool = False, sign_algorithm: str = OneLogin_Saml2_Constants.RSA_SHA256, digest_algorithm: str = OneLogin_Saml2_Constants.SHA256) -> str:

207

"""

208

Add XML digital signature to SAML documents.

209

210

Parameters:

211

- xml: XML document to sign

212

- key: Private key for signing

213

- cert: X.509 certificate

214

- debug: Enable debug mode

215

- sign_algorithm: Signature algorithm (default: RSA-SHA256)

216

- digest_algorithm: Digest algorithm (default: SHA256)

217

218

Returns:

219

Signed XML document

220

"""

221

222

@staticmethod

223

def validate_sign(xml: str, cert: str = None, fingerprint: str = None, fingerprintalg: str = 'sha1', validatecert: bool = False, debug: bool = False, xpath: str = None, multicerts: list = None, raise_exceptions: bool = False) -> bool:

224

"""

225

Validate XML signatures with multiple certificate support.

226

227

Parameters:

228

- xml: XML document to validate

229

- cert: X.509 certificate for validation

230

- fingerprint: Certificate fingerprint

231

- fingerprintalg: Fingerprint algorithm

232

- validatecert: Whether to validate certificate

233

- debug: Enable debug mode

234

- xpath: Specific XPath for signature element

235

- multicerts: List of certificates to try

236

- raise_exceptions: Whether to raise validation exceptions

237

238

Returns:

239

True if signature is valid

240

"""

241

242

@staticmethod

243

def validate_binary_sign(signed_query: str, signature: str, cert: str = None, algorithm: str = OneLogin_Saml2_Constants.RSA_SHA256, debug: bool = False) -> bool:

244

"""

245

Validate binary signatures (for GET requests).

246

247

Parameters:

248

- signed_query: Query string that was signed

249

- signature: Base64 encoded signature

250

- cert: X.509 certificate

251

- algorithm: Signature algorithm

252

- debug: Enable debug mode

253

254

Returns:

255

True if signature is valid

256

"""

257

```

258

259

### Encryption and Decryption

260

261

XML encryption handling for assertions and NameID protection.

262

263

```python { .api }

264

@staticmethod

265

def decrypt_element(encrypted_data: str, key: str, debug: bool = False, inplace: bool = False) -> str:

266

"""

267

Decrypt XML encrypted elements.

268

269

Parameters:

270

- encrypted_data: Encrypted XML element

271

- key: Private key for decryption

272

- debug: Enable debug mode

273

- inplace: Whether to decrypt in-place

274

275

Returns:

276

Decrypted XML element

277

"""

278

279

@staticmethod

280

def generate_name_id(value: str, sp_nq: str, sp_format: str = None, cert: str = None, debug: bool = False, nq: str = None) -> str:

281

"""

282

Generate NameID with optional encryption.

283

284

Parameters:

285

- value: NameID value

286

- sp_nq: SP Name Qualifier

287

- sp_format: NameID format

288

- cert: Certificate for encryption

289

- debug: Enable debug mode

290

- nq: Name Qualifier

291

292

Returns:

293

NameID XML element (encrypted if cert provided)

294

"""

295

```

296

297

### Time and Date Utilities

298

299

SAML timestamp handling with proper format conversion and validation.

300

301

```python { .api }

302

@staticmethod

303

def parse_time_to_SAML(time: int) -> str:

304

"""

305

Convert UNIX timestamp to SAML2 timestamp format.

306

307

Parameters:

308

- time: UNIX timestamp

309

310

Returns:

311

SAML timestamp string (ISO 8601 format)

312

"""

313

314

@staticmethod

315

def parse_SAML_to_time(timestr: str) -> int:

316

"""

317

Convert SAML2 timestamp to UNIX timestamp.

318

319

Parameters:

320

- timestr: SAML timestamp string

321

322

Returns:

323

UNIX timestamp integer

324

"""

325

326

@staticmethod

327

def now() -> int:

328

"""

329

Get current UNIX timestamp.

330

331

Returns:

332

Current timestamp as integer

333

"""

334

335

@staticmethod

336

def parse_duration(duration: str, timestamp: int = None) -> int:

337

"""

338

Interpret ISO8601 duration relative to timestamp.

339

340

Parameters:

341

- duration: ISO8601 duration string (e.g., "PT30M")

342

- timestamp: Base timestamp (default: current time)

343

344

Returns:

345

Resulting timestamp after adding duration

346

"""

347

```

348

349

### Utility Methods

350

351

Additional utility functions for ID generation and session management.

352

353

```python { .api }

354

@staticmethod

355

def generate_unique_id() -> str:

356

"""

357

Generate unique string for assertions using UUID and SHA1.

358

359

Returns:

360

Unique identifier string

361

"""

362

363

@staticmethod

364

def get_status(dom: str) -> dict:

365

"""

366

Extract status information from SAML Response.

367

368

Parameters:

369

- dom: SAML Response XML document

370

371

Returns:

372

Dictionary with status code and message

373

"""

374

375

@staticmethod

376

def delete_local_session(callback: callable = None) -> None:

377

"""

378

Delete local session with optional callback.

379

380

Parameters:

381

- callback: Optional function to call during session deletion

382

"""

383

```

384

385

## XML Processing and Security

386

387

Secure XML processing utilities with protection against XML vulnerabilities and comprehensive XPath operations.

388

389

```python { .api }

390

class OneLogin_Saml2_XML:

391

@staticmethod

392

def to_string(xml: object, **kwargs) -> str:

393

"""

394

Serialize XML element to encoded string with namespace cleanup.

395

396

Parameters:

397

- xml: XML element or document

398

- **kwargs: Additional serialization options

399

400

Returns:

401

Encoded XML string

402

"""

403

404

@staticmethod

405

def to_etree(xml: str) -> object:

406

"""

407

Parse XML from string/bytes to lxml Element with security.

408

409

Parameters:

410

- xml: XML string or bytes

411

412

Returns:

413

lxml Element object

414

415

Security Features:

416

- Forbids DTD processing

417

- Forbids entity resolution

418

- Strips comments and processing instructions

419

"""

420

421

@staticmethod

422

def validate_xml(xml: str, schema: str, debug: bool = False) -> bool:

423

"""

424

Validate XML against XSD schema files.

425

426

Parameters:

427

- xml: XML document to validate

428

- schema: XSD schema file path

429

- debug: Enable debug output

430

431

Returns:

432

True if XML is valid against schema

433

"""

434

```

435

436

### XPath Operations

437

438

Execute XPath queries with SAML namespace support and security features.

439

440

```python { .api }

441

@staticmethod

442

def query(dom: object, query: str, context: object = None, tagid: str = None) -> list:

443

"""

444

Execute XPath queries with SAML namespace support.

445

446

Parameters:

447

- dom: XML document or element

448

- query: XPath expression

449

- context: XPath context element

450

- tagid: Specific tag ID for context

451

452

Returns:

453

List of matching XML elements

454

"""

455

456

@staticmethod

457

def extract_tag_text(xml: str, tagname: str) -> str:

458

"""

459

Extract specific tag content as text.

460

461

Parameters:

462

- xml: XML document string

463

- tagname: Tag name to extract

464

465

Returns:

466

Tag text content

467

"""

468

469

@staticmethod

470

def element_text(node: object) -> str:

471

"""

472

Get element text content with comment stripping.

473

474

Parameters:

475

- node: XML element node

476

477

Returns:

478

Clean text content

479

"""

480

```

481

482

## SAML Constants and Specifications

483

484

Comprehensive constants for SAML 2.0 specifications, algorithms, and URIs.

485

486

```python { .api }

487

class OneLogin_Saml2_Constants:

488

# Clock drift allowance for timestamp validation

489

ALLOWED_CLOCK_DRIFT = 300 # seconds

490

```

491

492

### NameID Formats

493

494

Standard NameID format identifiers for different identity representations.

495

496

```python { .api }

497

# NameID Format Constants

498

NAMEID_EMAIL_ADDRESS = 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'

499

NAMEID_X509_SUBJECT_NAME = 'urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName'

500

NAMEID_WINDOWS_DOMAIN_QUALIFIED_NAME = 'urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName'

501

NAMEID_UNSPECIFIED = 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'

502

NAMEID_KERBEROS = 'urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos'

503

NAMEID_ENTITY = 'urn:oasis:names:tc:SAML:2.0:nameid-format:entity'

504

NAMEID_TRANSIENT = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'

505

NAMEID_PERSISTENT = 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'

506

NAMEID_ENCRYPTED = 'urn:oasis:names:tc:SAML:2.0:nameid-format:encrypted'

507

```

508

509

### Attribute Name Formats

510

511

Standard attribute name format identifiers for SAML attributes.

512

513

```python { .api }

514

# Attribute Name Format Constants

515

ATTRNAME_FORMAT_UNSPECIFIED = 'urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified'

516

ATTRNAME_FORMAT_URI = 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri'

517

ATTRNAME_FORMAT_BASIC = 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic'

518

```

519

520

### SAML Bindings

521

522

Protocol bindings for SAML message transport.

523

524

```python { .api }

525

# SAML Binding Constants

526

BINDING_HTTP_POST = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'

527

BINDING_HTTP_REDIRECT = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'

528

BINDING_HTTP_ARTIFACT = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact'

529

BINDING_SOAP = 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP'

530

BINDING_DEFLATE = 'urn:oasis:names:tc:SAML:2.0:bindings:URL-Encoding:DEFLATE'

531

```

532

533

### XML Namespaces

534

535

Standard XML namespace URIs for SAML processing.

536

537

```python { .api }

538

# SAML Namespaces

539

NS_SAML = 'urn:oasis:names:tc:SAML:2.0:assertion'

540

NS_SAMLP = 'urn:oasis:names:tc:SAML:2.0:protocol'

541

NS_SOAP = 'http://schemas.xmlsoap.org/soap/envelope/'

542

NS_MD = 'urn:oasis:names:tc:SAML:2.0:metadata'

543

NS_XS = 'http://www.w3.org/2001/XMLSchema'

544

NS_XSI = 'http://www.w3.org/2001/XMLSchema-instance'

545

NS_XENC = 'http://www.w3.org/2001/04/xmlenc#'

546

NS_DS = 'http://www.w3.org/2000/09/xmldsig#'

547

548

# Namespace Prefixes

549

NS_PREFIX_SAML = 'saml'

550

NS_PREFIX_SAMLP = 'samlp'

551

NS_PREFIX_MD = 'md'

552

NS_PREFIX_XS = 'xs'

553

NS_PREFIX_XSI = 'xsi'

554

NS_PREFIX_XSD = 'xsd'

555

NS_PREFIX_XENC = 'xenc'

556

NS_PREFIX_DS = 'ds'

557

558

# Namespace Map (Prefix:Namespace Mappings)

559

NSMAP = {

560

NS_PREFIX_SAMLP: NS_SAMLP,

561

NS_PREFIX_SAML: NS_SAML,

562

NS_PREFIX_DS: NS_DS,

563

NS_PREFIX_XENC: NS_XENC,

564

NS_PREFIX_MD: NS_MD

565

}

566

```

567

568

### Authentication Context

569

570

Authentication context class references for different authentication methods.

571

572

```python { .api }

573

# Authentication Context Constants

574

AC_UNSPECIFIED = 'urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified'

575

AC_PASSWORD = 'urn:oasis:names:tc:SAML:2.0:ac:classes:Password'

576

AC_PASSWORD_PROTECTED = 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'

577

AC_X509 = 'urn:oasis:names:tc:SAML:2.0:ac:classes:X509'

578

AC_SMARTCARD = 'urn:oasis:names:tc:SAML:2.0:ac:classes:Smartcard'

579

AC_KERBEROS = 'urn:oasis:names:tc:SAML:2.0:ac:classes:Kerberos'

580

```

581

582

### Subject Confirmation

583

584

Subject confirmation method identifiers for assertion validation.

585

586

```python { .api }

587

# Subject Confirmation Methods

588

CM_BEARER = 'urn:oasis:names:tc:SAML:2.0:cm:bearer'

589

CM_HOLDER_KEY = 'urn:oasis:names:tc:SAML:2.0:cm:holder-of-key'

590

CM_SENDER_VOUCHES = 'urn:oasis:names:tc:SAML:2.0:cm:sender-vouches'

591

```

592

593

### Status Codes

594

595

SAML response status codes for success and error conditions.

596

597

```python { .api }

598

# Status Code Constants

599

STATUS_SUCCESS = 'urn:oasis:names:tc:SAML:2.0:status:Success'

600

STATUS_REQUESTER = 'urn:oasis:names:tc:SAML:2.0:status:Requester'

601

STATUS_RESPONDER = 'urn:oasis:names:tc:SAML:2.0:status:Responder'

602

STATUS_VERSION_MISMATCH = 'urn:oasis:names:tc:SAML:2.0:status:VersionMismatch'

603

STATUS_NO_PASSIVE = 'urn:oasis:names:tc:SAML:2.0:status:NoPassive'

604

STATUS_PARTIAL_LOGOUT = 'urn:oasis:names:tc:SAML:2.0:status:PartialLogout'

605

STATUS_PROXY_COUNT_EXCEEDED = 'urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded'

606

```

607

608

### Cryptographic Algorithms

609

610

Algorithm identifiers for digital signatures, encryption, and hashing.

611

612

```python { .api }

613

# Hash Algorithms

614

SHA1 = 'http://www.w3.org/2000/09/xmldsig#sha1'

615

SHA256 = 'http://www.w3.org/2001/04/xmlenc#sha256'

616

SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#sha384'

617

SHA512 = 'http://www.w3.org/2001/04/xmlenc#sha512'

618

619

# Signature Algorithms

620

RSA_SHA1 = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'

621

RSA_SHA256 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'

622

RSA_SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384'

623

RSA_SHA512 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512'

624

625

# Encryption Algorithms

626

AES128_CBC = 'http://www.w3.org/2001/04/xmlenc#aes128-cbc'

627

AES192_CBC = 'http://www.w3.org/2001/04/xmlenc#aes192-cbc'

628

AES256_CBC = 'http://www.w3.org/2001/04/xmlenc#aes256-cbc'

629

RSA_1_5 = 'http://www.w3.org/2001/04/xmlenc#rsa-1_5'

630

RSA_OAEP_MGF1P = 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p'

631

632

# Deprecated Algorithms (security warnings)

633

DEPRECATED_ALGORITHMS = [DSA_SHA1, RSA_SHA1, SHA1]

634

```

635

636

## Error Handling

637

638

Comprehensive error classes with detailed error codes for different failure scenarios.

639

640

```python { .api }

641

class OneLogin_Saml2_Error(Exception):

642

def __init__(self, message: str, code: int = 0, errors: list = None):

643

"""

644

General SAML error with categorized error codes.

645

646

Parameters:

647

- message: Error description

648

- code: Numeric error code

649

- errors: List of additional error details

650

"""

651

652

class OneLogin_Saml2_ValidationError(OneLogin_Saml2_Error):

653

def __init__(self, message: str, code: int = 0, errors: list = None):

654

"""

655

SAML validation error with specific validation codes.

656

657

Parameters:

658

- message: Validation error description

659

- code: Validation error code

660

- errors: List of validation failure details

661

"""

662

```

663

664

### Error Code Categories

665

666

**General Error Codes:**

667

- `SETTINGS_FILE_NOT_FOUND` - Configuration file missing

668

- `SETTINGS_INVALID` - Invalid configuration values

669

- `CERT_NOT_FOUND` - Certificate not found

670

- `SAML_RESPONSE_NOT_FOUND` - SAML Response not found

671

- `SAML_SINGLE_LOGOUT_NOT_SUPPORTED` - SLO not supported

672

- `REDIRECT_INVALID_URL` - Invalid redirect URL

673

674

**Validation Error Codes:**

675

- `UNSUPPORTED_SAML_VERSION` - Unsupported SAML version

676

- `MISSING_ID` - Missing ID attribute

677

- `WRONG_NUMBER_OF_ASSERTIONS` - Incorrect assertion count

678

- `STATUS_CODE_IS_NOT_SUCCESS` - Non-success status

679

- `INVALID_SIGNATURE` - Invalid digital signature

680

- `ASSERTION_EXPIRED` - Assertion expired

681

- `WRONG_AUDIENCE` - Wrong audience restriction

682

- `WRONG_ISSUER` - Wrong issuer verification

683

- `RESPONSE_EXPIRED` - SAML Response expired

684

- `DEPRECATED_SIGNATURE_METHOD` - Deprecated signature method used

685

- `DEPRECATED_DIGEST_METHOD` - Deprecated digest method used

686

687

## Secure XML Processing

688

689

XML parsing functions with comprehensive security protections against XML vulnerabilities.

690

691

```python { .api }

692

def parse(source: str, parser: object = None, base_url: str = None, forbid_dtd: bool = True, forbid_entities: bool = True) -> object:

693

"""

694

Secure XML document parsing with vulnerability protection.

695

696

Parameters:

697

- source: XML source (file, URL, or string)

698

- parser: Custom XML parser

699

- base_url: Base URL for relative references

700

- forbid_dtd: Prevent DTD processing (security)

701

- forbid_entities: Prevent entity expansion (security)

702

703

Returns:

704

Parsed XML document tree

705

706

Security Features:

707

- DTD processing disabled

708

- Entity expansion disabled

709

- Network access disabled

710

- Comment and PI removal

711

"""

712

713

def fromstring(text: str, parser: object = None, base_url: str = None, forbid_dtd: bool = True, forbid_entities: bool = True) -> object:

714

"""

715

Secure XML string parsing with security protections.

716

717

Parameters:

718

- text: XML string to parse

719

- parser: Custom XML parser

720

- base_url: Base URL for relative references

721

- forbid_dtd: Prevent DTD processing

722

- forbid_entities: Prevent entity expansion

723

724

Returns:

725

Parsed XML element

726

"""

727

```

728

729

## Compatibility Functions

730

731

Python 2/3 compatibility utilities for consistent string and byte handling across versions.

732

733

```python { .api }

734

def utf8(data: str) -> str:

735

"""

736

Convert data to UTF-8 string with version compatibility.

737

738

Parameters:

739

- data: String or bytes data

740

741

Returns:

742

UTF-8 encoded string (Python version appropriate)

743

"""

744

745

def to_string(data: str) -> str:

746

"""

747

Convert data to string with proper encoding.

748

749

Parameters:

750

- data: String or bytes data

751

752

Returns:

753

String in appropriate format for Python version

754

"""

755

756

def to_bytes(data: str) -> bytes:

757

"""

758

Convert data to bytes with UTF-8 encoding.

759

760

Parameters:

761

- data: String data

762

763

Returns:

764

UTF-8 encoded bytes

765

"""

766

```

767

768

## Usage Patterns

769

770

### Certificate Validation

771

```python

772

from onelogin.saml2.utils import OneLogin_Saml2_Utils

773

774

# Validate XML signature with certificate

775

is_valid = OneLogin_Saml2_Utils.validate_sign(

776

xml_document,

777

cert=idp_certificate,

778

validatecert=True,

779

raise_exceptions=True

780

)

781

782

# Calculate certificate fingerprint

783

fingerprint = OneLogin_Saml2_Utils.calculate_x509_fingerprint(

784

certificate,

785

alg='sha256'

786

)

787

```

788

789

### Time Handling

790

```python

791

# Convert timestamps between formats

792

saml_time = OneLogin_Saml2_Utils.parse_time_to_SAML(time.time())

793

unix_time = OneLogin_Saml2_Utils.parse_SAML_to_time(saml_timestamp)

794

795

# Parse ISO8601 duration

796

expiry_time = OneLogin_Saml2_Utils.parse_duration("PT30M") # 30 minutes from now

797

```

798

799

### Secure XML Processing

800

```python

801

from onelogin.saml2.xml_utils import OneLogin_Saml2_XML

802

from onelogin.saml2.xmlparser import fromstring

803

804

# Secure XML parsing

805

xml_element = fromstring(xml_string, forbid_dtd=True, forbid_entities=True)

806

807

# XPath queries with SAML namespaces

808

assertions = OneLogin_Saml2_XML.query(xml_element, '//saml:Assertion')

809

810

# XML validation against schema

811

is_valid = OneLogin_Saml2_XML.validate_xml(xml_doc, 'saml-schema-assertion-2.0.xsd')

812

```

813

814

### Error Handling

815

```python

816

from onelogin.saml2.errors import OneLogin_Saml2_Error, OneLogin_Saml2_ValidationError

817

818

try:

819

auth.process_response()

820

except OneLogin_Saml2_ValidationError as e:

821

print(f"Validation failed: {e} (Code: {e.code})")

822

except OneLogin_Saml2_Error as e:

823

print(f"SAML error: {e} (Code: {e.code})")

824

```