382 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			382 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | |
| <html lang="en" prefix="og: https://ogp.me/ns#">
 | |
|     <head>
 | |
|         <meta charset="utf-8"/>
 | |
|         <title>Features overview | GrapheneOS</title>
 | |
|         <meta name="description" content="Overview of GrapheneOS features differentiating it from the Android Open Source Project (AOSP)."/>
 | |
|         <meta name="theme-color" content="#212121"/>
 | |
|         <meta name="color-scheme" content="dark light"/>
 | |
|         <meta name="msapplication-TileColor" content="#ffffff"/>
 | |
|         <meta name="viewport" content="width=device-width, initial-scale=1"/>
 | |
|         <meta name="twitter:site" content="@GrapheneOS"/>
 | |
|         <meta name="twitter:creator" content="@GrapheneOS"/>
 | |
|         <meta property="og:title" content="GrapheneOS features overview"/>
 | |
|         <meta property="og:description" content="Overview of GrapheneOS features differentiating it from the Android Open Source Project (AOSP)."/>
 | |
|         <meta property="og:type" content="website"/>
 | |
|         <meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
 | |
|         <meta property="og:image:width" content="512"/>
 | |
|         <meta property="og:image:height" content="512"/>
 | |
|         <meta property="og:image:alt" content="GrapheneOS logo"/>
 | |
|         <meta property="og:site_name" content="GrapheneOS"/>
 | |
|         <meta property="og:url" content="https://grapheneos.org/features"/>
 | |
|         <link rel="canonical" href="https://grapheneos.org/features"/>
 | |
|         <link rel="icon" href="/favicon.ico"/>
 | |
|         <link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
 | |
|         <link rel="mask-icon" href="{{path|/mask-icon.svg}}" color="#1a1a1a"/>
 | |
|         <link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
 | |
|         {{css|/main.css}}
 | |
|         <link rel="manifest" href="/manifest.webmanifest"/>
 | |
|         <link rel="license" href="/LICENSE.txt"/>
 | |
|     </head>
 | |
|     <body>
 | |
|         <header>
 | |
|             <nav id="site-menu">
 | |
|                 <ul>
 | |
|                     <li><a href="/"><img src="{{path|/mask-icon.svg}}" alt=""/>GrapheneOS</a></li>
 | |
|                     <li aria-current="page"><a href="/features">Features</a></li>
 | |
|                     <li><a href="/install/">Install</a></li>
 | |
|                     <li><a href="/build">Build</a></li>
 | |
|                     <li><a href="/usage">Usage</a></li>
 | |
|                     <li><a href="/faq">FAQ</a></li>
 | |
|                     <li><a href="/releases">Releases</a></li>
 | |
|                     <li><a href="/source">Source</a></li>
 | |
|                     <li><a href="/history/">History</a></li>
 | |
|                     <li><a href="/articles/">Articles</a></li>
 | |
|                     <li><a href="/donate">Donate</a></li>
 | |
|                     <li><a href="/contact">Contact</a></li>
 | |
|                 </ul>
 | |
|             </nav>
 | |
|         </header>
 | |
|         <main id="features">
 | |
|             <h1><a href="#features">Features overview</a></h1>
 | |
| 
 | |
|             <p>GrapheneOS is a private and secure mobile operating system with great functionality
 | |
|             and usability. It starts from the strong baseline of the
 | |
|             <a href="https://source.android.com/">Android Open Source Project (AOSP)</a> and
 | |
|             takes great care to avoid increasing attack surface or hurting the strong security
 | |
|             model. GrapheneOS makes substantial improvements to both privacy and security through
 | |
|             many carefully designed features built to function against real adversaries. The
 | |
|             project cares a lot about usability and app compatibility so those are taken into
 | |
|             account for all of our features.</p>
 | |
| 
 | |
|             <p>GrapheneOS is focused on substance rather than branding and marketing. It doesn't
 | |
|             take the typical approach of piling on a bunch of insecure features depending on the
 | |
|             adversaries not knowing about them and regressing actual privacy/security. It's a very
 | |
|             technical project building privacy and security into the OS rather than including
 | |
|             assorted unhelpful frills or bundling subjective third party apps choices.</p>
 | |
| 
 | |
|             <p>GrapheneOS is also hard at work on filling in gaps from not bundling Google apps
 | |
|             and services into the OS. We aren't against users using Google services but it doesn't
 | |
|             belong integrated into the OS in an invasive way. GrapheneOS won't take the shortcut
 | |
|             of simply bundling a very incomplete and poorly secured third party reimplementation
 | |
|             of Google services into the OS. That wouldn't ever be something users could rely upon.
 | |
|             It will also always be chasing a moving target while offering poorer security than the
 | |
|             real thing if the focus is on simply getting things working without great care for
 | |
|             doing it robustly and securely.</p>
 | |
| 
 | |
|             <p>This page provides an overview of currently implemented features differentiating
 | |
|             GrapheneOS from AOSP. It doesn't document our many historical features that are no
 | |
|             longer included for one reason or another. Many of our features were implemented in
 | |
|             AOSP, Linux, <a href="https://llvm.org/">LLVM</a> and other projects GrapheneOS is
 | |
|             based on and those aren't listed here. In many cases, we've been involved in getting
 | |
|             those features implemented in core infrastructure projects.</p>
 | |
| 
 | |
|             <nav id="table-of-contents">
 | |
|                 <h2><a href="#table-of-contents">Table of contents</a></h2>
 | |
| 
 | |
|                 <ul>
 | |
|                     <li><a href="#grapheneos">GrapheneOS</a></li>
 | |
|                     <li><a href="#services">Services</a></li>
 | |
|                     <li><a href="#project">Project</a></li>
 | |
|                 </ul>
 | |
|             </nav>
 | |
| 
 | |
|             <section id="grapheneos">
 | |
|                 <h2><a href="#grapheneos">GrapheneOS</a></h2>
 | |
| 
 | |
|                 <p>Partial list of GrapheneOS features beyond what AOSP 12 provides:</p>
 | |
| 
 | |
|                 <ul>
 | |
|                     <li>Hardened app runtime</li>
 | |
|                     <li>Stronger app sandbox</li>
 | |
|                     <li><a href="https://github.com/GrapheneOS/platform_bionic">Hardened libc</a>
 | |
|                     providing defenses against the most common classes of vulnerabilities (memory
 | |
|                     corruption)</li>
 | |
|                     <li>
 | |
|                         Our own <a href="https://github.com/GrapheneOS/hardened_malloc">hardened
 | |
|                         malloc (memory allocator)</a> leveraging modern hardware capabilities
 | |
|                         to provide substantial defenses against the most common classes of
 | |
|                         vulnerabilities (heap memory corruption) along with reducing the lifetime
 | |
|                         of sensitive data in memory. The <a
 | |
|                         href="https://github.com/GrapheneOS/hardened_malloc/blob/main/README.md">hardened_malloc
 | |
|                         README</a> has extensive documentation on it. The hardened_malloc
 | |
|                         project is portable to other Linux-based operating systems and is being
 | |
|                         adopted by other security-focused operating systems like Whonix.  Our
 | |
|                         allocator also heavily influenced the design of the <a
 | |
|                         href="https://www.openwall.com/lists/musl/2020/05/13/1">next-generation
 | |
|                         musl malloc implementation</a> which offers substantially better security than
 | |
|                         musl's previous malloc while still having minimal memory usage and code size.
 | |
|                         <ul>
 | |
|                             <li>Fully out-of-line metadata with protection from corruption, ruling
 | |
|                             out traditional allocator exploitation</li>
 | |
|                             <li>Separate memory regions for metadata, large allocations and each
 | |
|                             slab allocation size class with high entropy random bases and no
 | |
|                             address space reuse between the different regions</li>
 | |
|                             <li>Deterministic detection of any invalid free</li>
 | |
|                             <li>Zero-on-free with detection of write-after-free via checking that
 | |
|                             memory is still zeroed before handing it out again</li>
 | |
|                             <li>Delayed reuse of address space and memory allocations through the
 | |
|                             combination of deterministic and randomized quarantines to mitigate
 | |
|                             use-after-free vulnerabilities</li>
 | |
|                             <li>Fine-grained randomization</li>
 | |
|                             <li>Aggressive consistency checks</li>
 | |
|                             <li>Memory protected guard regions around allocations larger than 16k
 | |
|                             with randomization of guard region sizes for 128k and above</li>
 | |
|                             <li>Allocations smaller than 16k have guard regions around each of the
 | |
|                             slabs containing allocations (for example, 16 byte allocations are in
 | |
|                             4096 byte slabs with 4096 byte guard regions before and after)</li>
 | |
|                             <li>Random canaries with a leading zero are added to these smaller
 | |
|                             allocations to block C string overflows, absorb small overflows
 | |
|                             and detect linear overflows or other heap corruption when the
 | |
|                             canary value is checked (primarily on free)</li>
 | |
|                         </ul>
 | |
|                     </li>
 | |
|                     <li>Hardened compiler toolchain</li>
 | |
|                     <li>
 | |
|                         Hardened kernel
 | |
|                         <ul>
 | |
|                             <li>Support for dynamically loaded kernel modules is disabled and
 | |
|                             the minimal set of modules for the device model are built into the
 | |
|                             kernel to substantially improve the granularity of Control Flow
 | |
|                             Integrity (CFI) and reduce attack surface.</li>
 | |
|                             <li>4-level page tables are enabled on arm64 to provide a much larger
 | |
|                             address space (48-bit instead of 39-bit) with significantly higher
 | |
|                             entropy Address Space Layout Randomization (33-bit instead of
 | |
|                             24-bit).</li>
 | |
|                             <li>Random canaries with a leading zero are added to the kernel heap
 | |
|                             (slub) to block C string overflows, absorb small overflows and detect
 | |
|                             linear overflows or other heap corruption when the canary value is
 | |
|                             checked (on free, copies to/from userspace, etc.).</li>
 | |
|                             <li>Memory is wiped (zeroed) as soon as it's released in both the
 | |
|                             low-level kernel page allocator and higher level kernel heap allocator
 | |
|                             (slub). This substantially reduces the lifetime of sensitive data in
 | |
|                             memory, mitigates use-after-free vulnerabilities and makes most
 | |
|                             uninitialized data usage vulnerabilities harmless. Without our
 | |
|                             changes, memory that's released retains data indefinitely until the
 | |
|                             memory is handed out for other uses and gets partially or fully
 | |
|                             overwritten by new data.</li>
 | |
|                             <li>Kernel stack allocations are zeroed to make most uninitialized
 | |
|                             data usage vulnerabilities harmless.</li>
 | |
|                             <li>Assorted attack surface reduction through disabling features or
 | |
|                             setting up infrastructure to dynamically enable/disable them only as
 | |
|                             needed (perf, ptrace).</li>
 | |
|                             <li>Assorted upstream hardening features are enabled, including many
 | |
|                             which we played a part in developing and landing upstream as part of
 | |
|                             our linux-hardened project (which we intend to revive as a more active
 | |
|                             project again).</li>
 | |
|                         </ul>
 | |
|                     </li>
 | |
|                     <li>Prevention of dynamic native code execution in-memory or via the filesystem
 | |
|                     for the base OS without going via the package manager, etc.</li>
 | |
|                     <li>Filesystem access hardening</li>
 | |
|                     <li>Enhanced <a href="https://source.android.com/security/verifiedboot">verified boot</a>
 | |
|                     with better security properties and reduced attack surface</li>
 | |
|                     <li>Enhanced hardware-based attestation with more precise version information</li>
 | |
|                     <li>Eliminates remaining holes for apps to access hardware-based identifiers</li>
 | |
|                     <li>Greatly reduced remote, local and proximity-based attack surface by
 | |
|                     stripping out unnecessary code, making more features optional and disabling
 | |
|                     optional features by default (NFC, Bluetooth, etc.), when the screen is
 | |
|                     locked (connecting new USB peripherals, camera access) and optionally after a
 | |
|                     timeout (Bluetooth, Wi-Fi)</li>
 | |
|                     <li>Option to disable native debugging (ptrace) to reduce local attack surface
 | |
|                     (still enabled by default for compatibility)</li>
 | |
|                     <li>Low-level improvements to the <a href="/faq#encryption">filesystem-based
 | |
|                     full disk encryption</a> used on modern Android</li>
 | |
|                     <li>Support creating up to 16 secondary user profiles (15 + guest) instead of
 | |
|                     only 4 (3 + guest).</li>
 | |
|                     <li>Support for logging out of user profiles without needing a device manager:
 | |
|                     makes them inactive so that they can't continue running code while using
 | |
|                     another profile and purges the disk encryption keys (which are per-profile)
 | |
|                     from memory and hardware registers</li>
 | |
|                     <li>Option to enable automatically rebooting the device when no profile has
 | |
|                     been unlocked for the configured time period to put the device fully at rest
 | |
|                     again.</li>
 | |
|                     <li>Modern Microphone/Camera usage indicator UX is also used for Location.</li>
 | |
|                     <li>Improved user visibility into persistent firmware security through version
 | |
|                     and configuration verification with reporting of inconsistencies and debug
 | |
|                     features being enabled.</li>
 | |
|                     <li>Support for longer passwords by default (64 characters instead of 16)
 | |
|                     without requiring a device manager</li>
 | |
|                     <li>Stricter implementation of the optional fingerprint unlock feature permitting
 | |
|                     only 5 attempts rather than 20 before permanent lockout (our recommendation is
 | |
|                     still keeping sensitive data in user profiles without fingerprint unlock)</li>
 | |
|                     <li>Support for using the fingerprint scanner only for authentication in apps
 | |
|                     and unlocking hardware keystore keys by toggling off support for unlocking.</li>
 | |
|                     <li>PIN scrambling option</li>
 | |
|                     <li><a href="/usage#lte-only-mode">LTE-only mode</a> to reduce cellular radio
 | |
|                     attack surface by disabling enormous amounts of both legacy code (2G, 3G) and
 | |
|                     bleeding edge code (5G)</li>
 | |
|                     <li><a href="/usage#wifi-privacy-associated">Per-connection MAC randomization
 | |
|                     option (enabled by default)</a> as a more private option than the standard
 | |
|                     persistent per-network random MAC.</li>
 | |
|                     <li>When the per-connection MAC randomization added by GrapheneOS is being
 | |
|                     used, DHCP client state is flushed before reconnecting to a network to avoid
 | |
|                     revealing that it's likely the same device as before.</li>
 | |
|                     <li>Improved IPv6 privacy addresses to prevent tracking across networks</li>
 | |
|                     <li>Vanadium: hardened WebView and default browser — the WebView is what most
 | |
|                     other apps use to handle web content, so you benefit from Vanadium in many apps
 | |
|                     even if you choose another browser</li>
 | |
|                     <li>Hardware-based security verification and monitoring: the
 | |
|                     <a href="https://github.com/GrapheneOS/Auditor/releases">Auditor app</a> app and
 | |
|                     <a href="https://attestation.app/">attestation service</a> provide strong
 | |
|                     hardware-based verification of the authenticity and integrity of the
 | |
|                     firmware/software on the device. A strong pairing-based approach is used which
 | |
|                     also provides verification of the device's identity based on the hardware backed
 | |
|                     key generated for each pairing. Software-based checks are layered on top with
 | |
|                     trust securely chained from the hardware. For more details, see the
 | |
|                     <a href="https://attestation.app/about">about page</a>
 | |
|                     and <a href="https://attestation.app/tutorial">tutorial</a>.</li>
 | |
|                     <li><a href="https://github.com/GrapheneOS/PdfViewer">PDF Viewer</a>: sandboxed,
 | |
|                     hardened PDF viewer using HiDPI rendering with pinch to zoom, text selection,
 | |
|                     etc.</li>
 | |
|                     <li><a href="/usage#grapheneos-camera-app">GrapheneOS Camera</a>: modern
 | |
|                     camera app with a great user interface and a focus on privacy and
 | |
|                     security.</li>
 | |
|                     <li>Encrypted backups via integration of the
 | |
|                     <a href="https://github.com/seedvault-app/seedvault">Seedvault app</a> with
 | |
|                     support for local backups and any cloud storage provider with a storage provider
 | |
|                     app</li>
 | |
|                     <li><a href="/usage#exec-spawning">Secure application spawning system</a> avoiding
 | |
|                     sharing address space layout and other secrets across applications</li>
 | |
|                     <li>Network permission toggle for disallowing both direct and indirect access
 | |
|                     to any of the available networks. The device-local network (localhost) is also
 | |
|                     guarded by this permission, which is important for preventing apps from using
 | |
|                     it to communicate between profiles. Unlike a firewall-based implementation,
 | |
|                     the Network permission toggle prevents apps from using the network via APIs
 | |
|                     provided by the OS or other apps in the same profile as long as they're marked
 | |
|                     appropriately.</li>
 | |
|                     <li>The standard INTERNET permission used as the basis for the Network
 | |
|                     permission toggle is enhanced with a second layer of enforcement and proper
 | |
|                     support for granting/revoking it on a per-profile basis.</li>
 | |
|                     <li>Sensors permission toggle: disallow access to all other sensors not covered by
 | |
|                     existing Android permissions (Camera, Microphone, Body Sensors, Activity
 | |
|                     Recognition) including an accelerometer, gyroscope, compass, barometer,
 | |
|                     thermometer and any other sensors present on a given device. To avoid breaking
 | |
|                     compatibility with Android apps, the added permission is enabled by
 | |
|                     default.</li>
 | |
|                     <li>Authenticated encryption for network time updates via a first party server to
 | |
|                     prevent attackers from changing the time and enabling attacks based on bypassing
 | |
|                     certificate / key expiry, etc.</li>
 | |
|                     <li>Proper support for disabling network time updates rather than just not using
 | |
|                     the results</li>
 | |
|                     <li>Connectivity checks via a first party server with the option to revert to the
 | |
|                     standard checks (to blend in) or to fully disable them</li>
 | |
|                     <li>Hardened local build / signing infrastructure</li>
 | |
|                     <li><a href="/usage#updates">Seamless automatic OS update system</a> that just
 | |
|                     works and stays out of the way in the background without disrupting device
 | |
|                     usage, with full support for the standard automatic rollback if the first boot
 | |
|                     of the updated OS fails</li>
 | |
|                     <li>Require unlocking to access sensitive functionality via quick tiles</li>
 | |
|                     <li>Minor changes to default settings to prefer privacy over small conveniences:
 | |
|                     personalized keyboard suggestions based on gathering input history are disabled by
 | |
|                     default, sensitive notifications are hidden on the lockscreen by default and
 | |
|                     passwords are hidden during entry by default</li>
 | |
|                     <li><a href="/faq#bundled-apps">Minimal bundled apps and services</a>. Only
 | |
|                     essential apps are integrated into the OS. We don't make partnerships with
 | |
|                     apps and services to bundle them into the OS. An app may be the best choice
 | |
|                     today and poor choice in the future. Our approach will be recommending certain
 | |
|                     apps during the initial setup, not hard-wiring them into the OS.</li>
 | |
|                     <li>No Google apps and services. These can be used on GrapheneOS but only if
 | |
|                     they avoid requiring invasive OS integration. Building privileged support for
 | |
|                     Google services into the OS isn't something we're going to be doing, even if
 | |
|                     that's partially open source like microG.</li>
 | |
|                     <li><a href="/usage#sandboxed-play-services">Compatibility layer for coercing
 | |
|                     user installed Google Play services into running as sandboxed apps without any
 | |
|                     special privileges.</a></li>
 | |
|                     <li>Fixes for multiple serious vulnerabilities not yet fixed upstream due to a
 | |
|                     flexible release cycle / process prioritizing security.</li>
 | |
|                 </ul>
 | |
|             </section>
 | |
| 
 | |
|             <section id="services">
 | |
|                 <h2><a href="#services">Services</a></h2>
 | |
| 
 | |
|                 <p>Service infrastructure features:</p>
 | |
| 
 | |
|                 <ul>
 | |
|                     <li>Strict privacy and security practices for our infrastructure</li>
 | |
|                     <li>Unnecessary logging is avoided and logs are automatically purged after 10 days</li>
 | |
|                     <li>Services are hosted entirely via our own dedicated servers and virtual
 | |
|                     machines from OVH without involving any additional parties for CDNs, SaaS
 | |
|                     platforms, mirrors or other services</li>
 | |
|                     <li>Our services are built with open technology stacks to avoid being locked in to
 | |
|                     any particular hosting provider or vendor</li>
 | |
|                     <li>Open documentation on our infrastructure including listing out all of our
 | |
|                     services, guides on making similar setups, published configurations for each
 | |
|                     of our web services, etc.</li>
 | |
|                     <li>No proprietary services</li>
 | |
|                     <li>Authenticated encryption for all of our services</li>
 | |
|                     <li>Strong cipher configurations for all of our services (SSH, TLS, etc.) with
 | |
|                     only modern AEAD ciphers providing forward secrecy</li>
 | |
|                     <li>Our web sites do not include any third party content and entirely forbid
 | |
|                     it via strict Content Security Policy rules</li>
 | |
|                     <li>Our web sites disable referrer headers to maximize privacy</li>
 | |
|                     <li>Our web sites fully enable cross origin isolation and disable embedding in
 | |
|                     other content</li>
 | |
|                     <li><a href="https://internet.nl/faqs/dnssec/">DNSSEC</a> implemented for all
 | |
|                     of our domains to provide a root of trust for encryption and authentication
 | |
|                     for domain/server configuration</li>
 | |
|                     <li>DNS Certification Authority Authorization (CAA) records for all of our
 | |
|                     domains permitting only Let's Encrypt to issue certificates with fully
 | |
|                     integrated support for the experimental <code>accounturi</code> and
 | |
|                     <code>validationmethods</code> pinning our Let's Encrypt accounts as the only ones
 | |
|                     allowed to issue certificates</li>
 | |
|                     <li>DANE TLSA records for pinning keys for all our TLS services</li>
 | |
|                     <li>Our mail server enforces DNSSEC/DANE to provide authenticated encryption
 | |
|                     when sending mail including alert messages from the attestation service</li>
 | |
|                     <li>SSHFP across all domains for pinning SSH keys</li>
 | |
|                     <li>Static key pinning for our services in apps like Auditor</li>
 | |
|                     <li>Our web services use robust OCSP stapling with Must-Staple</li>
 | |
|                     <li>No persistent cookies or similar client-side state for anything other than
 | |
|                     login sessions, which are set up via SameSite=strict cookies and have
 | |
|                     server-side session tracking with the ability to log out of other
 | |
|                     sessions</li>
 | |
|                     <li>scrypt-based password hashing (likely Argon2 when the available implementations
 | |
|                     are more mature)</li>
 | |
|                 </ul>
 | |
|             </section>
 | |
| 
 | |
|             <section id="project">
 | |
|                 <h2><a href="#project">Project</a></h2>
 | |
| 
 | |
|                 <p>Beyond the technical features of the OS:</p>
 | |
| 
 | |
|                 <ul>
 | |
|                     <li>Collaborative, <a href="/source">open source project</a> with a
 | |
|                     <a href="/contact#community">very active community</a> and contributors</li>
 | |
|                     <li>Can make your own builds and make desired changes, so you aren't stuck with
 | |
|                     the decisions made by the upstream project</li>
 | |
|                     <li>Non-profit project avoiding conflicts of interest by keeping commercialization
 | |
|                     at a distance. Companies support the project
 | |
|                     <a href="/faq#company">rather than the project serving the needs of any
 | |
|                     particular company</a></li>
 | |
|                     <li><a href="/faq#privacy-policy">Strong privacy policies</a> across all our
 | |
|                     software and services</li>
 | |
|                     <li><a href="/history/">Proven track record</a> of the team standing up
 | |
|                     against attempts to compromise the integrity of the project and placing it
 | |
|                     above personal gain</li>
 | |
|                 </ul>
 | |
|             </section>
 | |
|         </main>
 | |
|         <footer>
 | |
|             <a href="/"><img src="{{path|/mask-icon.svg}}" width="512" height="512" alt=""/>GrapheneOS</a>
 | |
|             <ul id="social">
 | |
|                 <li><a href="https://twitter.com/GrapheneOS">Twitter</a></li>
 | |
|                 <li><a href="https://github.com/GrapheneOS">GitHub</a></li>
 | |
|                 <li><a href="https://reddit.com/r/GrapheneOS">Reddit</a></li>
 | |
|                 <li><a href="https://www.linkedin.com/company/grapheneos/">LinkedIn</a></li>
 | |
|             </ul>
 | |
|         </footer>
 | |
|     </body>
 | |
| </html>
 | 
