This commit is contained in:
libr
2026-03-03 10:12:22 +08:00
commit ae4c58e56d
223 changed files with 42635 additions and 0 deletions

196
.eslintrc Normal file
View File

@@ -0,0 +1,196 @@
{
"env": {
"browser": true
},
"extends": [
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"prettier",
"prettier/@typescript-eslint"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "tsconfig.json",
"sourceType": "module"
},
"ignorePatterns": ["src/__tests__/**/*"],
"plugins": [
"eslint-plugin-jsdoc",
"eslint-plugin-prefer-arrow",
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/restrict-template-expressions": "off",
"@typescript-eslint/adjacent-overload-signatures": "error",
"@typescript-eslint/array-type": [
"error",
{
"default": "array"
}
],
"@typescript-eslint/ban-types": [
"error",
{
"types": {
"Object": {
"message": "Avoid using the `Object` type. Did you mean `object`?"
},
"Function": {
"message": "Avoid using the `Function` type. Prefer a specific function type, like `() => void`."
},
"Boolean": {
"message": "Avoid using the `Boolean` type. Did you mean `boolean`?"
},
"Number": {
"message": "Avoid using the `Number` type. Did you mean `number`?"
},
"String": {
"message": "Avoid using the `String` type. Did you mean `string`?"
},
"Symbol": {
"message": "Avoid using the `Symbol` type. Did you mean `symbol`?"
}
}
}
],
"@typescript-eslint/consistent-type-assertions": "error",
"@typescript-eslint/dot-notation": "error",
"@typescript-eslint/indent": "off",
"@typescript-eslint/member-delimiter-style": [
"off",
{
"multiline": {
"delimiter": "none",
"requireLast": true
},
"singleline": {
"delimiter": "semi",
"requireLast": false
}
}
],
"@typescript-eslint/naming-convention": "error",
"@typescript-eslint/no-empty-function": "error",
"@typescript-eslint/no-empty-interface": "error",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-parameter-properties": "off",
"@typescript-eslint/no-unused-expressions": "error",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-var-requires": "error",
"@typescript-eslint/prefer-for-of": "error",
"@typescript-eslint/prefer-function-type": "error",
"@typescript-eslint/prefer-namespace-keyword": "error",
"@typescript-eslint/quotes": "off",
"@typescript-eslint/semi": [
"off",
null
],
"@typescript-eslint/triple-slash-reference": [
"error",
{
"path": "always",
"types": "prefer-import",
"lib": "always"
}
],
"@typescript-eslint/type-annotation-spacing": "off",
"@typescript-eslint/unified-signatures": "error",
"arrow-parens": [
"off",
"always"
],
"brace-style": [
"off",
"off"
],
"comma-dangle": "off",
"complexity": "off",
"constructor-super": "error",
"eol-last": "off",
"eqeqeq": [
"error",
"smart"
],
"guard-for-in": "error",
"id-blacklist": [
"error",
"any",
"Number",
"number",
"String",
"string",
"Boolean",
"boolean",
"Undefined",
"undefined"
],
"id-match": "error",
"jsdoc/check-alignment": "error",
"jsdoc/check-indentation": "error",
"jsdoc/newline-after-description": "error",
"linebreak-style": "off",
"max-classes-per-file": [
"error",
1
],
"max-len": "off",
"new-parens": "off",
"newline-per-chained-call": "off",
"no-bitwise": "error",
"no-caller": "error",
"no-cond-assign": "error",
"no-console": "error",
"no-debugger": "error",
"no-empty": "error",
"no-eval": "error",
"no-extra-semi": "off",
"no-fallthrough": "off",
"no-invalid-this": "off",
"no-irregular-whitespace": "off",
"no-multiple-empty-lines": "off",
"no-new-wrappers": "error",
"no-shadow": [
"error",
{
"hoist": "all"
}
],
"no-throw-literal": "error",
"no-trailing-spaces": "off",
"no-undef-init": "error",
"no-underscore-dangle": "error",
"no-unsafe-finally": "error",
"no-unused-labels": "error",
"no-var": "error",
"object-shorthand": "error",
"one-var": [
"error",
"never"
],
"prefer-arrow/prefer-arrow-functions": "error",
"prefer-const": "error",
"quote-props": "off",
"radix": "error",
"react/jsx-curly-spacing": "off",
"react/jsx-equals-spacing": "off",
"react/jsx-wrap-multilines": "off",
"space-before-function-paren": "off",
"space-in-parens": [
"off",
"never"
],
"spaced-comment": [
"error",
"always",
{
"markers": [
"/"
]
}
],
"use-isnan": "error",
"valid-typeof": "off"
}
}

33
.github/workflows/npm-publish.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
name: Node.js Package
on:
release:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16
- run: npm ci
- run: npm test
publish-npm:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
node_modules/
lib/
.idea/

5
.prettierrc Normal file
View File

@@ -0,0 +1,5 @@
{
"printWidth": 120,
"trailingComma": "all",
"singleQuote": true
}

28
AGENTS.md Normal file
View File

@@ -0,0 +1,28 @@
# AGENTS Guide
## Communication
- Reply to user in Chinese.
- Keep source code, identifiers, and comments in English.
## Package Manager
- Use `bun` for all Node.js dependency and script operations.
## Project Layout
- Core npm package source: `src/`
- High-level iMobileDevice interactions: `src/core/imobiledevice-client.ts`
- Browser demo app: `frontend/`
## Key Rule: Avoid Logic Duplication
- Do not re-implement usbmux/lockdown/AFC/InstProxy protocol logic in `frontend`.
- `frontend/src/main.ts` must consume root package exports from `webmuxd`.
- If behavior changes are needed, modify root package logic first, then wire it in frontend.
## Build & Validate
- Root build: `bun run build`
- Root lint: `bun run lint`
- Root test: `bun run test`
- Frontend build: `cd frontend && bun run build`
## Change Style
- Keep changes minimal, focused, and consistent with existing style.
- Prefer removing dead code over keeping legacy paths.

15
LICENSE Normal file
View File

@@ -0,0 +1,15 @@
Copyright 2021 Rick Mark <rickmark@outlook.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of
the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
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.

68
README.md Normal file
View File

@@ -0,0 +1,68 @@
# WebMuxD
`webmuxd` is a WebUSB implementation of Apple's `usbmuxd` protocol, compatible with [libimobiledevice/usbmuxd](https://github.com/libimobiledevice/usbmuxd).
## Usage
Yarn:
`yarn add webmuxd`
NPM:
`npm add webmuxd`
## iMobileDevice Interaction Module
This package now includes a browser-side high-level module for direct iOS interaction:
- `DirectUsbMuxClient`: usbmux + lockdownd + AFC + installation_proxy lifecycle
- `installIpaViaInstProxy`: staging IPA via AFC and installing with InstProxy
- Pairing helpers: `createHostId`, `createSystemBuid`, pair record encode/decode helpers
Import from root package:
`import { DirectUsbMuxClient, installIpaViaInstProxy } from "webmuxd"`
When device session requires TLS/pairing, inject your own `tlsFactory` and `pairRecordFactory` in `DirectUsbMuxClient` options.
## How it Works
In this repo you will find `webmuxd.ts`. This is a node module that provides the client side implementation of
connecting to the WebUSB API surface and configuring the message pump. You can see a more complete example and
implementation of this by looking at [webmuxd-example](https://github.com/webmuxd/webmuxd-example) and it's
corresponding server component [go-webmuxd](https://github.com/webmuxd/go-webmuxd). The example connects up this
component to a WebSocket and pipes the USB content back and forth to the `go-webmuxd` server, which finally passes
it to `libimobiledevice` via a UNIX socket on disk.
## Building
If you wish to create your own build it's rather simple:
`yarn run build`
## Developing
The simplest way to build, develop and diagnose is using the `XHC20` USB capture on macOS, and optionally `demuxusb`
https://www.umpah.net/how-to-sniff-usb-traffic-reverse-engineer-usb-device-interactions/
Using a Chromebook as an endpoint:
https://blog.rickmark.me/puppeteer-with-chromeos/
## Contributing and License
This project is happy to accept PRs and other contributions. It is free for commercial use under the MIT license,
I would love to see it credited if so!
## Roadmap
To make this component "production ready" and less of a proof of concept the following should be completed:
* Handle all `usbmuxd` framing, and ACKs in script to reduce RTT (round trip time)
* Create a standardized WebSocket protocol and move it from `webmuxd-example` to `webmuxd` keeping only the UI
* Move `MobileDevice.ts`
* Move `RemoteChannel.ts`
* Move `transport.proto` / `transport.ts`
* Factor out "common UI elements" to `webmuxd-ui`
* Device Picker
* Device Info
* Improve `go-webmuxd` as a multi-session "meet me" service

1224
bun.lock Normal file

File diff suppressed because it is too large Load Diff

24
frontend/.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

1381
frontend/bun.lock Normal file

File diff suppressed because it is too large Load Diff

12
frontend/index.html Normal file
View File

@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WebMuxD Demo</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

25
frontend/package.json Normal file
View File

@@ -0,0 +1,25 @@
{
"name": "frontend",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"serve": "vite preview",
"preview": "vite preview"
},
"dependencies": {
"@lbr77/anisette-js": "0.1.3",
"@lbr77/zsign-wasm-resigner-wrapper": "^0.1.5",
"altsign.js": "^0.1.2",
"fflate": "^0.8.2",
"jszip": "^3.10.1",
"node-forge": "^1.3.3",
"webmuxd": "file:.."
},
"devDependencies": {
"typescript": "~5.9.3",
"vite": "^7.3.1"
}
}

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

1
frontend/public/vite.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,39 @@
import type { HttpClient } from "@lbr77/anisette-js"
import { initLibcurl, libcurl } from "./anisette-libcurl-init"
export class LibcurlHttpClient implements HttpClient {
async get(url: string, headers: Record<string, string>): Promise<Uint8Array> {
await initLibcurl()
const response = await libcurl.fetch(url, {
method: "GET",
headers,
insecure: true,
_libcurl_http_version: 1.1,
})
if (!response.ok) {
throw new Error(`HTTP GET ${url} failed: ${response.status} ${response.statusText}`)
}
return new Uint8Array(await response.arrayBuffer())
}
async post(url: string, body: string, headers: Record<string, string>): Promise<Uint8Array> {
await initLibcurl()
const response = await libcurl.fetch(url, {
method: "POST",
body,
headers,
insecure: true,
_libcurl_http_version: 1.1,
})
if (!response.ok) {
throw new Error(`HTTP POST ${url} failed: ${response.status} ${response.statusText}`)
}
return new Uint8Array(await response.arrayBuffer())
}
}

View File

@@ -0,0 +1,26 @@
// @ts-ignore
import { libcurl } from "../public/anisette/libcurl_full.mjs"
let initialized = false
let initPromise: Promise<void> | null = null
export async function initLibcurl(): Promise<void> {
if (initialized) {
return
}
if (initPromise) {
return initPromise
}
initPromise = (async () => {
const wsProto = location.protocol === "https:" ? "wss:" : "ws:"
const wsUrl = `${wsProto}//${location.host}/wisp/`
libcurl.set_websocket(wsUrl)
await libcurl.load_wasm()
initialized = true
})()
return initPromise
}
export { libcurl }

View File

@@ -0,0 +1,76 @@
import { Anisette, loadWasmModule } from "@lbr77/anisette-js"
import { initLibcurl } from "./anisette-libcurl-init"
import { LibcurlHttpClient } from "./anisette-libcurl-http"
export interface AnisetteData {
machineID: string
oneTimePassword: string
localUserID: string
routingInfo: number
deviceUniqueIdentifier: string
deviceDescription: string
deviceSerialNumber: string
date: Date
locale: string
timeZone: string
}
let anisetteInstance: Anisette | null = null
export async function initAnisette(): Promise<Anisette> {
if (anisetteInstance) {
return anisetteInstance
}
await initLibcurl()
const httpClient = new LibcurlHttpClient()
const wasmModule = await loadWasmModule()
const [storeservicescore, coreadi] = await Promise.all([
fetch("/anisette/libstoreservicescore.so").then((response) => response.arrayBuffer()).then((arr) => new Uint8Array(arr)),
fetch("/anisette/libCoreADI.so").then((response) => response.arrayBuffer()).then((arr) => new Uint8Array(arr)),
])
anisetteInstance = await Anisette.fromSo(storeservicescore, coreadi, wasmModule, {
httpClient,
init: {
libraryPath: "./anisette/",
},
})
return anisetteInstance
}
export async function provisionAnisette(): Promise<void> {
const anisette = await initAnisette()
if (!anisette.isProvisioned) {
await anisette.provision()
}
}
export async function getAnisetteData(): Promise<AnisetteData> {
const anisette = await initAnisette()
if (!anisette.isProvisioned) {
await anisette.provision()
}
const headers = await anisette.getData()
return {
machineID: headers["X-Apple-I-MD-M"],
oneTimePassword: headers["X-Apple-I-MD"],
localUserID: headers["X-Apple-I-MD-LU"],
routingInfo: Number.parseInt(headers["X-Apple-I-MD-RINFO"], 10),
deviceUniqueIdentifier: headers["X-Mme-Device-Id"],
deviceDescription: headers["X-MMe-Client-Info"],
deviceSerialNumber: headers["X-Apple-I-SRL-NO"] || "0",
date: new Date(headers["X-Apple-I-Client-Time"]),
locale: headers["X-Apple-Locale"],
timeZone: headers["X-Apple-I-TimeZone"],
}
}
export function clearAnisetteCache(): void {
anisetteInstance = null
}

View File

@@ -0,0 +1,573 @@
import { strFromU8, unzipSync } from "fflate"
import {
AppleAPI,
Fetch,
signIPA,
type AnisetteData,
type AppID,
type Certificate,
type Device,
type Team,
} from "altsign.js"
import { initLibcurl, libcurl } from "./anisette-libcurl-init"
const SIGNING_IDENTITY_STORAGE_KEY = "webmuxd:signing-identities"
const PRIMARY_APP_INFO_PLIST_RE = /^Payload\/[^/]+\.app\/Info\.plist$/
interface ParsedIpaInfo {
bundleId?: string
displayName?: string
}
interface CachedSigningIdentityPayload {
certId: string
certPublicKeyBase64: string
privateKeyBase64: string
}
interface StoredSigningIdentityMap {
[appleAndTeamKey: string]: CachedSigningIdentityPayload
}
export interface AppleSigningCredentials {
appleId: string
password: string
}
export interface AppleSigningRequest {
ipaFile: File
anisetteData: AnisetteData
credentials: AppleSigningCredentials
deviceUdid: string
deviceName?: string
bundleIdOverride?: string
displayNameOverride?: string
onLog: (message: string) => void
}
export interface AppleSigningResult {
signedFile: File
outputBundleId: string
teamId: string
}
let appleApiInstance: AppleAPI | null = null
function getAppleApi(): AppleAPI {
if (appleApiInstance) {
return appleApiInstance
}
const appleFetch = new Fetch(initLibcurl, async (url, options) => {
const response = await libcurl.fetch(url, {
method: options.method,
headers: options.headers,
body: options.body,
redirect: "manual",
insecure: true,
_libcurl_http_version: 1.1,
} as never)
return response
})
appleApiInstance = new AppleAPI(appleFetch)
return appleApiInstance
}
export async function signIpaWithApple(
request: AppleSigningRequest,
): Promise<AppleSigningResult> {
const { ipaFile, anisetteData, credentials, onLog } = request
const ipaData = new Uint8Array(await ipaFile.arrayBuffer())
const ipaInfo = readIpaInfo(ipaData)
const bundleIdBase = (request.bundleIdOverride ?? ipaInfo.bundleId ?? "").trim()
if (bundleIdBase.length === 0) {
throw new Error("Cannot sign IPA: bundle identifier is missing")
}
const appleId = credentials.appleId.trim()
const password = credentials.password
if (!appleId || !password) {
throw new Error("Cannot sign IPA: Apple ID or password is empty")
}
onLog(`Signing stage: authenticating Apple account ${maskEmail(appleId)}...`)
const api = getAppleApi()
const { session } = await api.authenticate(appleId, password, anisetteData, (submitCode) => {
const code = window.prompt("Apple 2FA code")
if (!code || code.trim().length === 0) {
throw new Error("2FA code is required")
}
submitCode(code.trim())
})
const team = await api.fetchTeam(session)
onLog(`Signing stage: using team ${team.identifier} (${team.name}).`)
const finalBundleId = buildTeamScopedBundleId(bundleIdBase, team.identifier)
const displayName = (request.displayNameOverride ?? ipaInfo.displayName ?? "").trim()
const identity = await ensureSigningIdentity(api, session, team, appleId, onLog)
await ensureDeviceRegistered(
api,
session,
team,
request.deviceUdid,
request.deviceName,
onLog,
)
const appId = await ensureAppId(api, session, team, finalBundleId, onLog)
onLog("Signing stage: fetching provisioning profile...")
const provisioningProfile = await api.fetchProvisioningProfile(session, team, appId)
onLog("Signing stage: resigning IPA in browser...")
const signed = await signIPA({
ipaData,
certificate: identity.certificate.publicKey,
privateKey: identity.privateKey,
provisioningProfile: provisioningProfile.data,
bundleID: finalBundleId,
displayName: displayName.length > 0 ? displayName : undefined,
adhoc: false,
forceSign: true,
})
const outputFileName = toSignedFileName(ipaFile.name)
const signedArray = new Uint8Array(signed.data.byteLength)
signedArray.set(signed.data)
const signedBuffer = signedArray.buffer.slice(0)
const signedFile = new File([signedBuffer], outputFileName, {
type: "application/octet-stream",
})
onLog(`Signing stage: complete (${signed.data.byteLength} bytes).`)
return {
signedFile,
outputBundleId: finalBundleId,
teamId: team.identifier,
}
}
async function ensureSigningIdentity(
api: AppleAPI,
session: { anisetteData: AnisetteData; dsid: string; authToken: string },
team: Team,
appleId: string,
onLog: (message: string) => void,
): Promise<{ certificate: Certificate; privateKey: Uint8Array }> {
const certificates = await api.fetchCertificates(session, team)
const cached = loadCachedSigningIdentity(appleId, team.identifier)
if (cached) {
const matched = certificates.find((item) => item.identifier === cached.certId)
if (matched) {
onLog(`Signing stage: using cached certificate ${matched.identifier}.`)
return {
certificate: {
...matched,
publicKey: base64ToBytes(cached.certPublicKeyBase64),
},
privateKey: base64ToBytes(cached.privateKeyBase64),
}
}
}
onLog("Signing stage: creating development certificate...")
let created: { certificate: Certificate; privateKey: Uint8Array }
try {
created = await api.addCertificate(session, team, `webmuxd-${Date.now()}`)
} catch (error) {
const message = String(error)
if (!message.includes("7460") || certificates.length === 0) {
throw error
}
const target = certificates[0]
onLog(`Signing stage: certificate limit hit, revoking ${target.identifier}...`)
await api.revokeCertificate(session, team, target)
created = await api.addCertificate(session, team, `webmuxd-${Date.now()}`)
}
saveCachedSigningIdentity(appleId, team.identifier, {
certId: created.certificate.identifier,
certPublicKeyBase64: bytesToBase64(created.certificate.publicKey),
privateKeyBase64: bytesToBase64(created.privateKey),
})
onLog(`Signing stage: certificate ready ${created.certificate.identifier}.`)
return created
}
async function ensureDeviceRegistered(
api: AppleAPI,
session: { anisetteData: AnisetteData; dsid: string; authToken: string },
team: Team,
deviceUdid: string,
deviceName: string | undefined,
onLog: (message: string) => void,
): Promise<void> {
const normalizedUdid = normalizeUdid(deviceUdid)
if (!normalizedUdid) {
onLog("Signing stage: skip device registration because UDID is empty.")
return
}
let devices: Device[] = []
try {
devices = await api.fetchDevices(session, team)
} catch (error) {
onLog(`Signing stage: fetchDevices failed, skip registration check: ${formatError(error)}`)
}
const existed = findRegisteredDevice(devices, normalizedUdid)
if (existed) {
onLog(`Signing stage: device already registered (${existed.identifier}).`)
return
}
const registerName =
deviceName && deviceName.trim().length > 0
? deviceName.trim()
: `webmuxd-${normalizedUdid.slice(-6)}`
try {
onLog(`Signing stage: registering device ${normalizedUdid} as ${registerName}...`)
await api.registerDevice(session, team, registerName, normalizedUdid)
onLog(`Signing stage: device registered (${normalizedUdid}).`)
} catch (error) {
onLog(`Signing stage: register failed, skip and continue: ${formatError(error)}`)
try {
const latestDevices = await api.fetchDevices(session, team)
const registered = findRegisteredDevice(latestDevices, normalizedUdid)
if (registered) {
onLog(`Signing stage: device confirmed in developer list (${registered.identifier}).`)
return
}
} catch (verifyError) {
onLog(`Signing stage: device verify after failure also failed: ${formatError(verifyError)}`)
}
onLog("Signing stage: continue without registration (may affect profile generation).")
return
}
try {
const latestDevices = await api.fetchDevices(session, team)
const registered = findRegisteredDevice(latestDevices, normalizedUdid)
if (registered) {
onLog(`Signing stage: device confirmed in developer list (${registered.identifier}).`)
}
} catch (error) {
onLog(`Signing stage: device verification skipped: ${formatError(error)}`)
}
}
async function ensureAppId(
api: AppleAPI,
session: { anisetteData: AnisetteData; dsid: string; authToken: string },
team: Team,
bundleId: string,
onLog: (message: string) => void,
): Promise<AppID> {
const appIds = await api.fetchAppIDs(session, team)
const matched = appIds.find((item) => item.bundleIdentifier === bundleId)
if (matched) {
onLog(`Signing stage: reuse App ID ${bundleId}.`)
return matched
}
onLog(`Signing stage: creating App ID ${bundleId}...`)
return api.addAppID(session, team, "WebMuxD Signed App", bundleId)
}
function readIpaInfo(ipaBytes: Uint8Array): ParsedIpaInfo {
const files = unzipSync(ipaBytes, {
filter: (file) => PRIMARY_APP_INFO_PLIST_RE.test(file.name),
})
const infoName = Object.keys(files).find((name) => PRIMARY_APP_INFO_PLIST_RE.test(name))
if (!infoName) {
return {}
}
const plistData = parseInfoPlist(files[infoName])
if (!plistData || typeof plistData !== "object" || Array.isArray(plistData)) {
return {}
}
const data = plistData as Record<string, unknown>
const bundleId =
typeof data.CFBundleIdentifier === "string" ? (data.CFBundleIdentifier as string) : undefined
const displayName =
typeof data.CFBundleDisplayName === "string"
? (data.CFBundleDisplayName as string)
: typeof data.CFBundleName === "string"
? (data.CFBundleName as string)
: undefined
return { bundleId, displayName }
}
function parseInfoPlist(infoPlistBytes: Uint8Array): unknown {
if (strFromU8(infoPlistBytes.subarray(0, 8)) === "bplist00") {
return parseBinaryPlist(infoPlistBytes)
}
const xml = strFromU8(infoPlistBytes)
return parseXmlPlist(xml)
}
function parseXmlPlist(xml: string): unknown {
const doc = new DOMParser().parseFromString(xml, "application/xml")
const parserError = doc.querySelector("parsererror")
if (parserError) {
return {}
}
const root = doc.querySelector("plist > *")
if (!root) {
return {}
}
return parseXmlNode(root)
}
function parseXmlNode(node: Element): unknown {
switch (node.tagName) {
case "dict": {
const map: Record<string, unknown> = {}
const children = Array.from(node.children)
for (let i = 0; i < children.length - 1; i += 2) {
const keyNode = children[i]
const valueNode = children[i + 1]
if (keyNode.tagName !== "key") {
continue
}
map[keyNode.textContent ?? ""] = parseXmlNode(valueNode)
}
return map
}
case "array":
return Array.from(node.children).map((child) => parseXmlNode(child))
case "string":
case "date":
return node.textContent ?? ""
case "integer":
return Number.parseInt(node.textContent ?? "0", 10)
case "real":
return Number.parseFloat(node.textContent ?? "0")
case "true":
return true
case "false":
return false
case "data":
return base64ToBytes((node.textContent ?? "").trim())
default:
return node.textContent ?? ""
}
}
function parseBinaryPlist(bytes: Uint8Array): unknown {
if (bytes.length < 40 || strFromU8(bytes.subarray(0, 8)) !== "bplist00") {
throw new Error("Invalid binary plist")
}
const trailerOffset = bytes.length - 32
const offsetSize = bytes[trailerOffset + 6]
const objectRefSize = bytes[trailerOffset + 7]
const objectCount = readUInt(bytes, trailerOffset + 8, 8)
const topObject = readUInt(bytes, trailerOffset + 16, 8)
const offsetTableStart = readUInt(bytes, trailerOffset + 24, 8)
const objectOffsets = new Array<number>(objectCount)
for (let i = 0; i < objectCount; i += 1) {
const entryOffset = offsetTableStart + i * offsetSize
objectOffsets[i] = readUInt(bytes, entryOffset, offsetSize)
}
const memo = new Map<number, unknown>()
const readLength = (offset: number, objectInfo: number): { length: number; nextOffset: number } => {
if (objectInfo < 0x0f) {
return { length: objectInfo, nextOffset: offset + 1 }
}
const marker = bytes[offset + 1]
const markerType = marker >> 4
const markerInfo = marker & 0x0f
if (markerType !== 0x1) {
throw new Error("Invalid binary plist length marker")
}
const intSize = 1 << markerInfo
const intOffset = offset + 2
return {
length: readUInt(bytes, intOffset, intSize),
nextOffset: intOffset + intSize,
}
}
const parseObject = (index: number): unknown => {
if (memo.has(index)) {
return memo.get(index)
}
const offset = objectOffsets[index]
const marker = bytes[offset]
const objectType = marker >> 4
const objectInfo = marker & 0x0f
let value: unknown
if (objectType === 0x0) {
value = objectInfo === 0x8 ? false : objectInfo === 0x9
} else if (objectType === 0x1) {
value = readUInt(bytes, offset + 1, 1 << objectInfo)
} else if (objectType === 0x2) {
const realSize = 1 << objectInfo
const view = new DataView(bytes.buffer, bytes.byteOffset + offset + 1, realSize)
value = realSize === 4 ? view.getFloat32(0, false) : view.getFloat64(0, false)
} else if (objectType === 0x5) {
const { length, nextOffset } = readLength(offset, objectInfo)
value = strFromU8(bytes.subarray(nextOffset, nextOffset + length))
} else if (objectType === 0x6) {
const { length, nextOffset } = readLength(offset, objectInfo)
value = decodeUtf16Be(bytes.subarray(nextOffset, nextOffset + length * 2))
} else if (objectType === 0xa) {
const { length, nextOffset } = readLength(offset, objectInfo)
const items: unknown[] = []
for (let i = 0; i < length; i += 1) {
const ref = readUInt(bytes, nextOffset + i * objectRefSize, objectRefSize)
items.push(parseObject(ref))
}
value = items
} else if (objectType === 0xd) {
const { length, nextOffset } = readLength(offset, objectInfo)
const map: Record<string, unknown> = {}
const valuesOffset = nextOffset + length * objectRefSize
for (let i = 0; i < length; i += 1) {
const keyRef = readUInt(bytes, nextOffset + i * objectRefSize, objectRefSize)
const valueRef = readUInt(bytes, valuesOffset + i * objectRefSize, objectRefSize)
const key = parseObject(keyRef)
if (typeof key === "string") {
map[key] = parseObject(valueRef)
}
}
value = map
} else {
value = null
}
memo.set(index, value)
return value
}
return parseObject(topObject)
}
function readUInt(bytes: Uint8Array, offset: number, length: number): number {
let value = 0
for (let i = 0; i < length; i += 1) {
value = value * 256 + bytes[offset + i]
}
return value
}
function decodeUtf16Be(bytes: Uint8Array): string {
let text = ""
for (let i = 0; i + 1 < bytes.length; i += 2) {
text += String.fromCharCode((bytes[i] << 8) | bytes[i + 1])
}
return text
}
function buildTeamScopedBundleId(baseBundleId: string, teamId: string): string {
const trimmedBase = baseBundleId.trim()
const trimmedTeam = teamId.trim()
if (!trimmedBase || !trimmedTeam) {
return trimmedBase
}
const lowerBase = trimmedBase.toLowerCase()
const lowerTeam = trimmedTeam.toLowerCase()
if (lowerBase.endsWith(`.${lowerTeam}`)) {
return trimmedBase
}
return `${trimmedBase}.${trimmedTeam}`
}
function toSignedFileName(name: string): string {
if (!name.toLowerCase().endsWith(".ipa")) {
return `${name}-signed.ipa`
}
return `${name.slice(0, -4)}-signed.ipa`
}
function loadCachedSigningIdentity(
appleId: string,
teamId: string,
): CachedSigningIdentityPayload | null {
const map = loadSigningIdentityMap()
const key = signingIdentityKey(appleId, teamId)
const value = map[key]
if (!value || !value.certId || !value.certPublicKeyBase64 || !value.privateKeyBase64) {
return null
}
return value
}
function saveCachedSigningIdentity(
appleId: string,
teamId: string,
payload: CachedSigningIdentityPayload,
): void {
const map = loadSigningIdentityMap()
map[signingIdentityKey(appleId, teamId)] = payload
window.localStorage.setItem(SIGNING_IDENTITY_STORAGE_KEY, JSON.stringify(map))
}
function loadSigningIdentityMap(): StoredSigningIdentityMap {
const raw = window.localStorage.getItem(SIGNING_IDENTITY_STORAGE_KEY)
if (!raw) {
return {}
}
try {
const parsed = JSON.parse(raw) as unknown
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
return {}
}
return parsed as StoredSigningIdentityMap
} catch {
return {}
}
}
function signingIdentityKey(appleId: string, teamId: string): string {
return `${appleId.trim().toLowerCase()}::${teamId.trim().toUpperCase()}`
}
function bytesToBase64(value: Uint8Array): string {
let binary = ""
for (const byte of value) {
binary += String.fromCharCode(byte)
}
return btoa(binary)
}
function base64ToBytes(base64: string): Uint8Array {
const normalized = base64.replace(/\s+/g, "")
const binary = atob(normalized)
const out = new Uint8Array(binary.length)
for (let i = 0; i < binary.length; i += 1) {
out[i] = binary.charCodeAt(i)
}
return out
}
function maskEmail(value: string): string {
const trimmed = value.trim()
const at = trimmed.indexOf("@")
if (at <= 1) {
return "***"
}
return `${trimmed.slice(0, 2)}***${trimmed.slice(at)}`
}
function findRegisteredDevice(devices: readonly Device[], normalizedUdid: string): Device | null {
return (
devices.find((item) => normalizeUdid(item.identifier) === normalizedUdid) ?? null
)
}
function normalizeUdid(value: string): string {
return value.trim().toUpperCase()
}
function formatError(error: unknown): string {
if (error instanceof Error) {
return error.message
}
return String(error)
}

9
frontend/src/counter.ts Normal file
View File

@@ -0,0 +1,9 @@
export function setupCounter(element: HTMLButtonElement) {
let counter = 0
const setCounter = (count: number) => {
counter = count
element.innerHTML = `count is ${counter}`
}
element.addEventListener('click', () => setCounter(counter + 1))
setCounter(0)
}

775
frontend/src/main.ts Normal file
View File

@@ -0,0 +1,775 @@
import "./style.css"
import * as webmuxdModule from "webmuxd"
import { getAnisetteData, provisionAnisette, type AnisetteData } from "./anisette-service"
import { signIpaWithApple } from "./apple-signing"
import initOpensslWasm, {
libimobiledevice_generate_pair_record,
OpensslClient,
} from "../../tls/openssl-wasm/pkg/openssl_wasm.js"
interface WebUsbTransportInstance {
readonly isOpen: boolean
open(): Promise<void>
close(): Promise<void>
send(data: ArrayBuffer): Promise<void>
setDataHandler(handler: ((data: ArrayBuffer) => void) | null): void
setDisconnectHandler(handler: ((reason?: unknown) => void) | null): void
}
interface WebUsbTransportCtor {
supported(): boolean
requestAppleDevice(): Promise<WebUsbTransportInstance>
}
interface PairRecord {
hostId: string
systemBuid: string
hostCertificatePem: string
hostPrivateKeyPem: string
rootCertificatePem: string
rootPrivateKeyPem: string
deviceCertificatePem: string
devicePublicKey: Uint8Array
escrowBag?: Uint8Array
}
interface StoredPairRecordPayload {
hostId: string
systemBuid: string
hostCertificatePem: string
hostPrivateKeyPem: string
rootCertificatePem: string
rootPrivateKeyPem: string
deviceCertificatePem: string
devicePublicKey: string
escrowBag: string | null
}
interface StartSessionResult {
sessionId: string
enableSessionSsl: boolean
}
interface DirectUsbMuxClient {
readonly isHandshakeComplete: boolean
readonly isLockdownConnected: boolean
readonly isAfcConnected: boolean
readonly isInstProxyConnected: boolean
readonly isSessionStarted: boolean
readonly isSessionSslEnabled: boolean
readonly isTlsActive: boolean
readonly isPaired: boolean
loadPairRecord(record: PairRecord | null): void
openAndHandshake(): Promise<void>
connectLockdown(port?: number): Promise<void>
getOrFetchDeviceUdid(): Promise<string>
getOrFetchDeviceName(): Promise<string | null>
pairDevice(hostId: string, systemBuid: string): Promise<PairRecord>
startSession(hostId: string, systemBuid: string): Promise<StartSessionResult>
close(): Promise<void>
}
interface DirectUsbMuxClientCtor {
new (
transport: WebUsbTransportInstance,
options?: {
log?: (message: string) => void
onStateChange?: () => void
lockdownLabel?: string
tlsFactory?: {
ensureReady?: () => Promise<void>
createConnection(request: {
serverName: string
caCertificatePem: string
certificatePem: string
privateKeyPem: string
}): {
is_handshaking(): boolean
write_plaintext(data: Uint8Array): void
feed_tls(data: Uint8Array): void
take_tls_out(): Uint8Array
take_plain_out(): Uint8Array
free(): void
}
}
pairRecordFactory?: {
createPairRecord(request: {
devicePublicKey: Uint8Array
hostId: string
systemBuid: string
}): Promise<PairRecord>
}
},
): DirectUsbMuxClient
}
interface SigningPreflightContext {
anisetteData: AnisetteData
preparedAtIso: string
}
interface WasmPairRecordPayload {
hostId: string
systemBuid: string
hostCertificatePem: string
hostPrivateKeyPem: string
rootCertificatePem: string
rootPrivateKeyPem: string
deviceCertificatePem: string
}
const LOCKDOWN_PORT = 62078
const HOST_ID_STORAGE_KEY = "webmuxd:host-id"
const SYSTEM_BUID_STORAGE_KEY = "webmuxd:system-buid"
const PAIR_RECORDS_STORAGE_KEY = "webmuxd:pair-records-by-udid"
const LEGACY_PAIR_RECORD_STORAGE_KEY = "webmuxd:pair-record"
const APPLE_ID_STORAGE_KEY = "webmuxd:apple-id"
const SIGN_BUNDLE_ID_STORAGE_KEY = "webmuxd:sign-bundle-id"
const SIGN_DISPLAY_NAME_STORAGE_KEY = "webmuxd:sign-display-name"
const ENABLE_BROWSER_SIGNING_PIPELINE = true
const SIGNING_PREFLIGHT_REQUIRED = false
const webmuxdModuleValue = webmuxdModule as unknown as Record<string, unknown>
const WebUsbTransport = resolveWebmuxdExport<WebUsbTransportCtor>(
webmuxdModuleValue,
"WebUsbTransport",
)
const WebmuxdDirectUsbMuxClient = resolveWebmuxdExport<DirectUsbMuxClientCtor>(
webmuxdModuleValue,
"DirectUsbMuxClient",
)
const webmuxdInstallIpaViaInstProxy = resolveWebmuxdExport<
(
client: DirectUsbMuxClient,
ipaData: Uint8Array,
fileName: string,
onLog?: (message: string) => void,
) => Promise<void>
>(webmuxdModuleValue, "installIpaViaInstProxy")
const webmuxdSanitizeIpaFileName = resolveWebmuxdExport<(fileName: string) => string>(
webmuxdModuleValue,
"sanitizeIpaFileName",
)
const webmuxdCreateHostId = resolveWebmuxdExport<() => string>(
webmuxdModuleValue,
"createHostId",
)
const webmuxdCreateSystemBuid = resolveWebmuxdExport<() => string>(
webmuxdModuleValue,
"createSystemBuid",
)
const webmuxdEncodeStoredPairRecord = resolveWebmuxdExport<
(record: PairRecord) => StoredPairRecordPayload
>(webmuxdModuleValue, "encodeStoredPairRecord")
const webmuxdDecodeStoredPairRecord = resolveWebmuxdExport<
(payload: StoredPairRecordPayload) => PairRecord | null
>(webmuxdModuleValue, "decodeStoredPairRecord")
let opensslInitPromise: Promise<void> | null = null
const ensureOpensslReady = async (): Promise<void> => {
if (!opensslInitPromise) {
opensslInitPromise = initOpensslWasm().then(() => undefined)
}
await opensslInitPromise
}
const app = document.querySelector<HTMLDivElement>("#app")
if (!app) {
throw new Error("App root is missing")
}
app.innerHTML = `
<main class="shell">
<section class="panel">
<p class="eyebrow">Pure Browser usbmux + lockdown</p>
<h1>WebMuxD Direct Mode</h1>
<p class="subline">
Handshake with iPhone USB MUX directly, then connect lockdownd (62078).
</p>
<div id="ipa-drop-zone" class="drop-zone">
Drag & drop IPA here to run full flow: Signing Preflight -> Select Device -> Session -> Upload -> Install
</div>
<div class="request-row">
<label for="host-id">HostID</label>
<input id="host-id" type="text" />
</div>
<div class="request-row">
<label for="system-buid">SystemBUID</label>
<input id="system-buid" type="text" />
</div>
<div class="request-row">
<label for="apple-id">Apple ID</label>
<input id="apple-id" type="email" autocomplete="username" />
</div>
<div class="request-row">
<label for="apple-password">Apple Password</label>
<input id="apple-password" type="password" autocomplete="current-password" />
</div>
<div class="request-row">
<label for="sign-bundle-id">Sign BundleID</label>
<input id="sign-bundle-id" type="text" placeholder="optional" />
</div>
<div class="request-row">
<label for="sign-display-name">Sign DisplayName</label>
<input id="sign-display-name" type="text" placeholder="optional" />
</div>
<div class="request-row">
<label for="ipa-file">Select IPA</label>
<input id="ipa-file" type="file" accept=".ipa,application/octet-stream" />
</div>
<div class="state-grid">
<div class="state-item">
<span class="label">WebUSB</span>
<span id="support-state" class="value"></span>
</div>
<div class="state-item">
<span class="label">Transport</span>
<span id="transport-state" class="value"></span>
</div>
<div class="state-item">
<span class="label">MUX</span>
<span id="mux-state" class="value"></span>
</div>
<div class="state-item">
<span class="label">Lockdown TCP</span>
<span id="lockdown-state" class="value"></span>
</div>
<div class="state-item">
<span class="label">Pair</span>
<span id="pair-state" class="value"></span>
</div>
<div class="state-item">
<span class="label">Lockdown Session</span>
<span id="session-state" class="value"></span>
</div>
<div class="state-item">
<span class="label">AFC</span>
<span id="afc-state" class="value"></span>
</div>
<div class="state-item">
<span class="label">InstProxy</span>
<span id="instproxy-state" class="value"></span>
</div>
</div>
</section>
<section class="log-panel">
<div class="log-head">
<h2>Event Log</h2>
</div>
<pre id="log" class="log"></pre>
</section>
</main>
`
const hostIdInput = mustGetInput("host-id")
const systemBuidInput = mustGetInput("system-buid")
const appleIdInput = mustGetInput("apple-id")
const applePasswordInput = mustGetInput("apple-password")
const signBundleIdInput = mustGetInput("sign-bundle-id")
const signDisplayNameInput = mustGetInput("sign-display-name")
const ipaFileInput = mustGetInput("ipa-file")
const supportState = mustGetElement("support-state")
const transportState = mustGetElement("transport-state")
const muxState = mustGetElement("mux-state")
const lockdownState = mustGetElement("lockdown-state")
const pairState = mustGetElement("pair-state")
const sessionState = mustGetElement("session-state")
const afcState = mustGetElement("afc-state")
const instProxyState = mustGetElement("instproxy-state")
const ipaDropZone = mustGetElement("ipa-drop-zone")
const logView = mustGetElement("log")
const logLines: string[] = []
const isSupported = WebUsbTransport.supported()
let directClient: DirectUsbMuxClient | null = null
let installFlowInProgress = false
let signingPreflightPromise: Promise<SigningPreflightContext | null> | null = null
hostIdInput.value = getOrCreateHostId()
systemBuidInput.value = getOrCreateSystemBuid()
appleIdInput.value = loadText(APPLE_ID_STORAGE_KEY) ?? ""
applePasswordInput.value = ""
signBundleIdInput.value = loadText(SIGN_BUNDLE_ID_STORAGE_KEY) ?? ""
signDisplayNameInput.value = loadText(SIGN_DISPLAY_NAME_STORAGE_KEY) ?? ""
const addLog = (message: string): void => {
const now = new Date()
const time = `${now.toLocaleTimeString()}.${String(now.getMilliseconds()).padStart(3, "0")}`
logLines.push(`[${time}] ${message}`)
logView.textContent = logLines.slice(-200).join("\n")
}
const refreshState = (): void => {
supportState.textContent = isSupported ? "supported" : "not supported"
transportState.textContent = directClient ? "selected" : "not selected"
muxState.textContent = directClient?.isHandshakeComplete ? "ready" : "pending"
lockdownState.textContent = directClient?.isLockdownConnected ? "connected" : "disconnected"
pairState.textContent = directClient?.isPaired ? "paired" : "not paired"
sessionState.textContent = directClient?.isSessionStarted
? directClient.isSessionSslEnabled
? directClient.isTlsActive
? "started (tls active)"
: "started (ssl required)"
: "started"
: "not started"
afcState.textContent = directClient?.isAfcConnected ? "connected" : "disconnected"
instProxyState.textContent = directClient?.isInstProxyConnected ? "connected" : "disconnected"
}
const ensureClientSelected = async (): Promise<DirectUsbMuxClient> => {
if (directClient) {
return directClient
}
const transport = await WebUsbTransport.requestAppleDevice()
directClient = new WebmuxdDirectUsbMuxClient(transport, {
log: addLog,
onStateChange: refreshState,
lockdownLabel: "webmuxd.frontend",
tlsFactory: {
ensureReady: ensureOpensslReady,
createConnection: (request) => {
return new OpensslClient(
request.serverName,
request.caCertificatePem,
request.certificatePem,
request.privateKeyPem,
)
},
},
pairRecordFactory: {
createPairRecord: async (request) => {
return await createPairRecord(request.devicePublicKey, request.hostId, request.systemBuid)
},
},
})
addLog("Apple device selected.")
refreshState()
return directClient
}
const getSigningCredentials = (): { appleId: string; password: string } | null => {
const appleId = appleIdInput.value.trim()
const password = applePasswordInput.value
if (!appleId || !password) {
return null
}
return { appleId, password }
}
const prepareSigningPreflight = async (
log: (message: string) => void,
): Promise<SigningPreflightContext | null> => {
if (signingPreflightPromise) {
return signingPreflightPromise
}
signingPreflightPromise = (async () => {
try {
log("Signing preflight: provisioning anisette...")
await provisionAnisette()
const anisetteData = await getAnisetteData()
const context: SigningPreflightContext = {
anisetteData,
preparedAtIso: new Date().toISOString(),
}
log(
`Signing preflight ready: machineID=${shortToken(anisetteData.machineID)}, locale=${anisetteData.locale}, timezone=${anisetteData.timeZone}`,
)
return context
} catch (error) {
const message = formatError(error)
log(`Signing preflight failed: ${message}`)
if (SIGNING_PREFLIGHT_REQUIRED) {
throw error
}
log("Signing preflight skipped (non-blocking mode).")
return null
}
})()
try {
return await signingPreflightPromise
} finally {
signingPreflightPromise = null
}
}
const prepareIpaForInstall = async (
ipaFile: File,
log: (message: string) => void,
device: { udid: string; name?: string },
): Promise<{ installFile: File; signingContext: SigningPreflightContext | null }> => {
const signingContext = await prepareSigningPreflight(log)
if (signingContext) {
log(`Signing preflight timestamp: ${signingContext.preparedAtIso}`)
}
if (!ENABLE_BROWSER_SIGNING_PIPELINE) {
log("Signing stage: browser resign pipeline is disabled, using original IPA.")
return { installFile: ipaFile, signingContext }
}
if (!signingContext) {
log("Signing stage: anisette is unavailable, using original IPA.")
return { installFile: ipaFile, signingContext: null }
}
const credentials = getSigningCredentials()
if (!credentials) {
log("Signing stage: Apple ID/password not set, using original IPA.")
return { installFile: ipaFile, signingContext }
}
const bundleIdOverride = signBundleIdInput.value.trim()
const displayNameOverride = signDisplayNameInput.value.trim()
const signingResult = await signIpaWithApple({
ipaFile,
anisetteData: signingContext.anisetteData,
credentials,
deviceUdid: device.udid,
deviceName: device.name,
bundleIdOverride: bundleIdOverride.length > 0 ? bundleIdOverride : undefined,
displayNameOverride: displayNameOverride.length > 0 ? displayNameOverride : undefined,
onLog: log,
})
log(
`Signing stage: signed IPA ready (${signingResult.signedFile.name}), bundleId=${signingResult.outputBundleId}, team=${signingResult.teamId}.`,
)
return { installFile: signingResult.signedFile, signingContext }
}
const installIpaViaInstProxy = async (
client: DirectUsbMuxClient,
ipaFile: File,
log: (message: string) => void,
): Promise<void> => {
const rawData = new Uint8Array(await ipaFile.arrayBuffer())
const safeFileName = webmuxdSanitizeIpaFileName(ipaFile.name)
await webmuxdInstallIpaViaInstProxy(client, rawData, safeFileName, log)
}
const runFullInstallFlow = async (ipaFile: File): Promise<void> => {
if (installFlowInProgress) {
throw new Error("Install flow is already running")
}
installFlowInProgress = true
try {
addLog(`Full install start: ${ipaFile.name} (${ipaFile.size} bytes).`)
const client = await ensureClientSelected()
let hostId = hostIdInput.value.trim()
let systemBuid = systemBuidInput.value.trim()
if (hostId.length === 0) {
hostId = getOrCreateHostId()
hostIdInput.value = hostId
}
if (systemBuid.length === 0) {
systemBuid = getOrCreateSystemBuid()
systemBuidInput.value = systemBuid
}
saveText(HOST_ID_STORAGE_KEY, hostId)
saveText(SYSTEM_BUID_STORAGE_KEY, systemBuid)
if (!client.isHandshakeComplete) {
await client.openAndHandshake()
}
if (!client.isLockdownConnected) {
await client.connectLockdown(LOCKDOWN_PORT)
}
const deviceUdid = await client.getOrFetchDeviceUdid()
const deviceName = await client.getOrFetchDeviceName()
addLog(`Device UDID: ${deviceUdid}`)
if (deviceName) {
addLog(`Device Name: ${deviceName}`)
}
const prepared = await prepareIpaForInstall(ipaFile, addLog, {
udid: deviceUdid,
name: deviceName ?? undefined,
})
const storedPair = loadPairRecordForUdid(deviceUdid)
if (storedPair && !client.isPaired) {
client.loadPairRecord(storedPair)
hostId = storedPair.hostId
systemBuid = storedPair.systemBuid
hostIdInput.value = hostId
systemBuidInput.value = systemBuid
saveText(HOST_ID_STORAGE_KEY, hostId)
saveText(SYSTEM_BUID_STORAGE_KEY, systemBuid)
addLog(`Loaded pair record for device ${deviceUdid}.`)
}
if (!client.isPaired) {
const pairResult = await client.pairDevice(hostId, systemBuid)
savePairRecordForUdid(deviceUdid, pairResult)
addLog(`Pair success and pair record saved for ${deviceUdid}.`)
}
if (!client.isSessionStarted) {
const session = await client.startSession(hostId, systemBuid)
addLog(
`StartSession success: SessionID=${session.sessionId}, EnableSessionSSL=${String(session.enableSessionSsl)}`,
)
}
await installIpaViaInstProxy(client, prepared.installFile, addLog)
} finally {
installFlowInProgress = false
}
}
const handleSelectedIpaFile = async (file: File): Promise<void> => {
addLog(`IPA selected: ${file.name} (${file.size} bytes).`)
refreshState()
try {
await runFullInstallFlow(file)
} catch (error) {
addLog(`Install IPA failed: ${formatError(error)}`)
} finally {
refreshState()
}
}
appleIdInput.addEventListener("change", () => {
saveText(APPLE_ID_STORAGE_KEY, appleIdInput.value.trim())
})
signBundleIdInput.addEventListener("change", () => {
saveText(SIGN_BUNDLE_ID_STORAGE_KEY, signBundleIdInput.value.trim())
})
signDisplayNameInput.addEventListener("change", () => {
saveText(SIGN_DISPLAY_NAME_STORAGE_KEY, signDisplayNameInput.value.trim())
})
ipaFileInput.addEventListener("change", async () => {
const file = ipaFileInput.files && ipaFileInput.files.length > 0 ? ipaFileInput.files[0] : null
if (!file) {
addLog("IPA selection cleared.")
refreshState()
return
}
await handleSelectedIpaFile(file)
})
ipaDropZone.addEventListener("dragenter", (event) => {
event.preventDefault()
ipaDropZone.classList.add("dragover")
})
ipaDropZone.addEventListener("dragover", (event) => {
event.preventDefault()
ipaDropZone.classList.add("dragover")
})
ipaDropZone.addEventListener("dragleave", () => {
ipaDropZone.classList.remove("dragover")
})
ipaDropZone.addEventListener("drop", async (event) => {
event.preventDefault()
ipaDropZone.classList.remove("dragover")
const file = event.dataTransfer?.files?.[0] ?? null
if (!file) {
addLog("Drop ignored: no file.")
return
}
await handleSelectedIpaFile(file)
})
window.addEventListener("beforeunload", () => {
void directClient?.close()
})
addLog("Demo ready.")
refreshState()
function mustGetElement(id: string): HTMLElement {
const element = document.getElementById(id)
if (!element) {
throw new Error(`Element #${id} not found`)
}
return element
}
function mustGetInput(id: string): HTMLInputElement {
const element = document.getElementById(id)
if (!element || !(element instanceof HTMLInputElement)) {
throw new Error(`Input #${id} not found`)
}
return element
}
function loadText(key: string): string | null {
return window.localStorage.getItem(key)
}
function saveText(key: string, value: string): void {
window.localStorage.setItem(key, value)
}
function getOrCreateHostId(): string {
const existing = loadText(HOST_ID_STORAGE_KEY)
if (existing && existing.trim().length > 0) {
return existing
}
const created = webmuxdCreateHostId()
saveText(HOST_ID_STORAGE_KEY, created)
return created
}
function getOrCreateSystemBuid(): string {
const existing = loadText(SYSTEM_BUID_STORAGE_KEY)
if (existing && existing.trim().length > 0) {
return existing
}
const created = webmuxdCreateSystemBuid()
saveText(SYSTEM_BUID_STORAGE_KEY, created)
return created
}
function readPairRecordMap(): Record<string, StoredPairRecordPayload> {
const text = loadText(PAIR_RECORDS_STORAGE_KEY)
if (!text) {
return {}
}
try {
const parsed = JSON.parse(text) as unknown
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
return {}
}
return parsed as Record<string, StoredPairRecordPayload>
} catch {
return {}
}
}
function writePairRecordMap(map: Record<string, StoredPairRecordPayload>): void {
saveText(PAIR_RECORDS_STORAGE_KEY, JSON.stringify(map))
}
function savePairRecordForUdid(udid: string, record: PairRecord): void {
const normalizedUdid = udid.trim()
if (normalizedUdid.length === 0) {
return
}
const map = readPairRecordMap()
map[normalizedUdid] = webmuxdEncodeStoredPairRecord(record)
writePairRecordMap(map)
}
function loadLegacyPairRecord(): PairRecord | null {
const text = loadText(LEGACY_PAIR_RECORD_STORAGE_KEY)
if (!text) {
return null
}
try {
const parsed = JSON.parse(text) as StoredPairRecordPayload
return webmuxdDecodeStoredPairRecord(parsed)
} catch {
return null
}
}
function loadPairRecordForUdid(udid: string): PairRecord | null {
const normalizedUdid = udid.trim()
if (normalizedUdid.length === 0) {
return null
}
const map = readPairRecordMap()
const fromMap = map[normalizedUdid]
if (fromMap) {
try {
return webmuxdDecodeStoredPairRecord(fromMap)
} catch {
return null
}
}
const legacy = loadLegacyPairRecord()
if (legacy) {
savePairRecordForUdid(normalizedUdid, legacy)
window.localStorage.removeItem(LEGACY_PAIR_RECORD_STORAGE_KEY)
}
return legacy
}
async function createPairRecord(
devicePublicKeyBytes: Uint8Array,
hostId: string,
systemBuid: string,
): Promise<PairRecord> {
await ensureOpensslReady()
const payloadText = libimobiledevice_generate_pair_record(
new Uint8Array(devicePublicKeyBytes),
hostId,
systemBuid,
)
const payload = JSON.parse(payloadText) as WasmPairRecordPayload
return {
hostId: payload.hostId,
systemBuid: payload.systemBuid,
hostCertificatePem: normalizePem(payload.hostCertificatePem),
hostPrivateKeyPem: normalizePem(payload.hostPrivateKeyPem),
rootCertificatePem: normalizePem(payload.rootCertificatePem),
rootPrivateKeyPem: normalizePem(payload.rootPrivateKeyPem),
deviceCertificatePem: normalizePem(payload.deviceCertificatePem),
devicePublicKey: new Uint8Array(devicePublicKeyBytes),
}
}
function normalizePem(value: string): string {
const normalized = value.replace(/\0/g, "").replace(/\r\n/g, "\n").trim()
return `${normalized}\n`
}
function shortToken(value: string): string {
const text = value.trim()
if (text.length <= 10) {
return text
}
return `${text.slice(0, 6)}...${text.slice(-4)}`
}
function formatError(error: unknown): string {
if (error instanceof Error) {
return error.message
}
return String(error)
}
function resolveWebmuxdExport<T>(moduleValue: Record<string, unknown>, key: string): T {
const direct = moduleValue[key]
if (direct !== undefined) {
return direct as T
}
const defaultValue = moduleValue.default
if (defaultValue && typeof defaultValue === "object") {
const fromDefault = (defaultValue as Record<string, unknown>)[key]
if (fromDefault !== undefined) {
return fromDefault as T
}
}
throw new Error(`webmuxd export ${key} is unavailable`)
}

2
frontend/src/node-forge.d.ts vendored Normal file
View File

@@ -0,0 +1,2 @@
declare module "node-forge"

196
frontend/src/style.css Normal file
View File

@@ -0,0 +1,196 @@
@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap");
:root {
--bg-top: #f7f1e6;
--bg-bottom: #e8dcc3;
--panel: rgba(255, 249, 238, 0.82);
--ink: #1f2a36;
--ink-soft: #5c6672;
--accent: #d64f2a;
--accent-2: #0c7f7a;
--border: rgba(31, 42, 54, 0.16);
}
* {
box-sizing: border-box;
}
body {
margin: 0;
min-width: 320px;
min-height: 100vh;
font-family: "Space Grotesk", "Segoe UI", sans-serif;
color: var(--ink);
background:
radial-gradient(circle at 14% 16%, rgba(214, 79, 42, 0.3), transparent 42%),
radial-gradient(circle at 82% 8%, rgba(12, 127, 122, 0.25), transparent 36%),
linear-gradient(170deg, var(--bg-top), var(--bg-bottom));
}
#app {
max-width: 1160px;
margin: 0 auto;
padding: 32px 20px 48px;
}
.shell {
display: grid;
gap: 16px;
grid-template-columns: 1.1fr 0.9fr;
}
.panel,
.log-panel {
background: var(--panel);
border: 1px solid var(--border);
border-radius: 20px;
backdrop-filter: blur(6px);
}
.panel {
padding: 28px;
}
.eyebrow {
margin: 0;
color: var(--accent-2);
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
font-size: 12px;
}
h1 {
margin: 10px 0 4px;
font-size: clamp(1.8rem, 5vw, 2.8rem);
line-height: 1.05;
}
.subline {
margin: 0;
color: var(--ink-soft);
}
.drop-zone {
margin-top: 18px;
border: 2px dashed rgba(12, 127, 122, 0.45);
border-radius: 14px;
padding: 16px 14px;
text-align: center;
font-size: 13px;
font-weight: 600;
color: var(--accent-2);
background: rgba(12, 127, 122, 0.08);
transition: border-color 120ms ease, background-color 120ms ease, transform 120ms ease;
}
.drop-zone.dragover {
border-color: var(--accent);
background: rgba(214, 79, 42, 0.12);
transform: translateY(-1px);
}
.request-row {
margin-top: 12px;
display: grid;
grid-template-columns: 140px 1fr;
gap: 10px;
align-items: center;
}
.request-row label {
font-size: 12px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--ink-soft);
}
.request-row input {
width: 100%;
border-radius: 10px;
border: 1px solid var(--border);
background: rgba(255, 255, 255, 0.7);
color: var(--ink);
padding: 10px 12px;
font-size: 14px;
font-family: "IBM Plex Mono", "SFMono-Regular", Menlo, monospace;
}
.request-row input:focus {
outline: 2px solid rgba(12, 127, 122, 0.24);
border-color: rgba(12, 127, 122, 0.45);
}
.state-grid {
margin-top: 20px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 10px;
}
.state-item {
border: 1px solid var(--border);
border-radius: 12px;
padding: 10px 12px;
display: grid;
gap: 6px;
}
.label {
font-size: 11px;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--ink-soft);
}
.value {
font-size: 16px;
font-weight: 700;
}
.log-panel {
padding: 20px;
display: grid;
grid-template-rows: auto 1fr;
min-height: 430px;
}
.log-head {
display: flex;
justify-content: space-between;
align-items: center;
}
h2 {
margin: 0;
font-size: 18px;
}
.log {
margin: 12px 0 0;
padding: 14px;
border-radius: 14px;
border: 1px solid var(--border);
background: rgba(28, 36, 46, 0.96);
color: #d5f4ef;
font-family: "IBM Plex Mono", "SFMono-Regular", Menlo, monospace;
font-size: 12px;
line-height: 1.45;
overflow: auto;
white-space: pre-wrap;
}
@media (max-width: 860px) {
.shell {
grid-template-columns: 1fr;
}
.request-row {
grid-template-columns: 1fr;
}
.state-grid {
grid-template-columns: 1fr;
}
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path fill="#007ACC" d="M0 128v128h256V0H0z"></path><path fill="#FFF" d="m56.612 128.85l-.081 10.483h33.32v94.68h23.568v-94.68h33.321v-10.28c0-5.69-.122-10.444-.284-10.566c-.122-.162-20.4-.244-44.983-.203l-44.74.122l-.121 10.443Zm149.955-10.742c6.501 1.625 11.459 4.51 16.01 9.224c2.357 2.52 5.851 7.111 6.136 8.208c.08.325-11.053 7.802-17.798 11.988c-.244.162-1.22-.894-2.317-2.52c-3.291-4.795-6.745-6.867-12.028-7.233c-7.76-.528-12.759 3.535-12.718 10.321c0 1.992.284 3.17 1.097 4.795c1.707 3.536 4.876 5.649 14.832 9.956c18.326 7.883 26.168 13.084 31.045 20.48c5.445 8.249 6.664 21.415 2.966 31.208c-4.063 10.646-14.14 17.879-28.323 20.276c-4.388.772-14.79.65-19.504-.203c-10.28-1.828-20.033-6.908-26.047-13.572c-2.357-2.6-6.949-9.387-6.664-9.874c.122-.163 1.178-.813 2.356-1.504c1.138-.65 5.446-3.129 9.509-5.485l7.355-4.267l1.544 2.276c2.154 3.29 6.867 7.801 9.712 9.305c8.167 4.307 19.383 3.698 24.909-1.26c2.357-2.153 3.332-4.388 3.332-7.68c0-2.966-.366-4.266-1.91-6.501c-1.99-2.845-6.054-5.242-17.595-10.24c-13.206-5.69-18.895-9.224-24.096-14.832c-3.007-3.25-5.852-8.452-7.03-12.8c-.975-3.617-1.22-12.678-.447-16.335c2.723-12.76 12.353-21.659 26.25-24.3c4.51-.853 14.994-.528 19.424.569Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

4
frontend/src/webmuxd-shim.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
declare module "webmuxd" {
const webmuxd: Record<string, unknown>
export default webmuxd
}

26
frontend/tsconfig.json Normal file
View File

@@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "ES2022",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"types": ["vite/client"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src"]
}

29
frontend/vite.config.ts Normal file
View File

@@ -0,0 +1,29 @@
import { defineConfig } from "vite"
import { dirname, resolve } from "node:path"
import { fileURLToPath } from "node:url"
const frontendDir = dirname(fileURLToPath(import.meta.url))
const repoRootDir = resolve(frontendDir, "..")
export default defineConfig({
server: {
fs: {
allow: [repoRootDir],
},
proxy: {
"/api": "http://localhost:8080",
"/wisp": { target: "ws://localhost:8080", ws: true },
},
},
resolve: {
preserveSymlinks: true,
},
optimizeDeps: {
include: ["webmuxd", "@lbr77/anisette-js/browser"],
},
build: {
commonjsOptions: {
include: [/node_modules/, /\/lib\/webmuxd\.js/, /\/lib\/core\/.*\.js/],
},
},
})

7
jestconfig.json Normal file
View File

@@ -0,0 +1,7 @@
{
"transform": {
"^.+\\.(t|j)sx?$": "ts-jest"
},
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"]
}

46
package.json Normal file
View File

@@ -0,0 +1,46 @@
{
"name": "webmuxd",
"version": "0.8.1",
"description": "WebUSB implementation of Apple Mobile Device usbmuxd",
"homepage": "https://github.com/webmuxd/webmuxd#readme",
"repository": {
"type": "git",
"url": "https://github.com/webmuxd/webmuxd"
},
"bugs": {
"url": "https://github.com/webmuxd/webmuxd/issues"
},
"main": "lib/webmuxd.js",
"files": [
"lib/**/*"
],
"scripts": {
"build": "tsc",
"prepare": "npm run build",
"prepublishOnly": "npm test && npm run lint",
"preversion": "npm run lint",
"version": "npm run format && git add -A src",
"postversion": "git push && git push --tags",
"format": "prettier --write \"src/**/*.ts\"",
"lint": "eslint --ext .ts src/",
"test": "jest --config jestconfig.json"
},
"author": "Rick Mark",
"license": "MIT",
"devDependencies": {
"@types/jest": "^26.0.15",
"@typescript-eslint/eslint-plugin": "^5.7.0",
"@typescript-eslint/parser": "^5.7.0",
"eslint": "^8.4.1",
"eslint-config-prettier": "^6.14.0",
"eslint-plugin-jsdoc": "^37.2.1",
"eslint-plugin-prefer-arrow": "^1.2.2",
"jest": "^26.6.0",
"prettier": "^2.1.2",
"ts-jest": "^26.4.1",
"typescript": "^4.5.4"
},
"dependencies": {
"@types/w3c-web-usb": "^1.0.4"
}
}

View File

@@ -0,0 +1,131 @@
import { BrowserUsbMuxClient } from "../core/browser-usbmux-client"
import {
decodeHeader,
encodeHeader,
USBMUX_HEADER_SIZE,
UsbMuxMessageType,
} from "../core/usbmux-protocol"
import { UsbMuxSession } from "../core/usbmux-session"
import { DataHandler, DisconnectHandler, UsbMuxTransport } from "../core/transport"
class MockTransport implements UsbMuxTransport {
isOpen = false
dataHandler: DataHandler | null = null
disconnectHandler: DisconnectHandler | null = null
sent: ArrayBuffer[] = []
async open(): Promise<void> {
this.isOpen = true
}
async close(): Promise<void> {
this.isOpen = false
}
async send(data: ArrayBuffer): Promise<void> {
this.sent.push(new Uint8Array(data).slice().buffer)
}
setDataHandler(handler: DataHandler | null): void {
this.dataHandler = handler
}
setDisconnectHandler(handler: DisconnectHandler | null): void {
this.disconnectHandler = handler
}
emit(data: Uint8Array): void {
this.dataHandler?.(data.slice().buffer)
}
}
const buildPacket = (tag: number, payloadText: string): Uint8Array => {
const payload = new Uint8Array(Buffer.from(payloadText, "utf8"))
const header = encodeHeader({
length: USBMUX_HEADER_SIZE + payload.byteLength,
version: 1,
message: UsbMuxMessageType.plist,
tag,
})
const packet = new Uint8Array(USBMUX_HEADER_SIZE + payload.byteLength)
packet.set(new Uint8Array(header), 0)
packet.set(payload, USBMUX_HEADER_SIZE)
return packet
}
test("UsbMuxSession handles fragmented packet", async () => {
const transport = new MockTransport()
const session = new UsbMuxSession(transport)
const packets: Array<{ tag: number; payload: string }> = []
session.onPacket((packet) => {
packets.push({
tag: packet.header.tag,
payload: Buffer.from(packet.payload).toString("utf8"),
})
})
await session.start()
const packet = buildPacket(7, "first")
transport.emit(packet.slice(0, 9))
expect(packets).toHaveLength(0)
transport.emit(packet.slice(9))
expect(packets).toEqual([{ tag: 7, payload: "first" }])
})
test("UsbMuxSession handles multiple packets in one read", async () => {
const transport = new MockTransport()
const session = new UsbMuxSession(transport)
const tags: number[] = []
session.onPacket((packet) => tags.push(packet.header.tag))
await session.start()
const first = buildPacket(1, "a")
const second = buildPacket(2, "b")
const merged = new Uint8Array(first.byteLength + second.byteLength)
merged.set(first, 0)
merged.set(second, first.byteLength)
transport.emit(merged)
expect(tags).toEqual([1, 2])
})
test("UsbMuxSession drops invalid header length and continues on next read", async () => {
const transport = new MockTransport()
const session = new UsbMuxSession(transport)
const tags: number[] = []
session.onPacket((packet) => tags.push(packet.header.tag))
await session.start()
const invalid = new Uint8Array(
encodeHeader({
length: 8,
version: 1,
message: UsbMuxMessageType.plist,
tag: 99,
}),
)
transport.emit(invalid)
expect(tags).toEqual([])
transport.emit(buildPacket(3, "ok"))
expect(tags).toEqual([3])
})
test("BrowserUsbMuxClient connect sends network-byte-order port", async () => {
const transport = new MockTransport()
const client = new BrowserUsbMuxClient(transport)
await client.start()
await client.connect(42, 62078)
expect(transport.sent).toHaveLength(1)
const sent = transport.sent[0]
const header = decodeHeader(sent.slice(0, USBMUX_HEADER_SIZE))
expect(header.message).toBe(UsbMuxMessageType.plist)
const payload = Buffer.from(sent.slice(USBMUX_HEADER_SIZE)).toString("utf8")
expect(payload).toContain("<key>DeviceID</key><integer>42</integer>")
expect(payload).toContain("<key>PortNumber</key><integer>32498</integer>")
expect(payload).toContain("<key>MessageType</key><string>Connect</string>")
})

View File

@@ -0,0 +1,16 @@
import MobileDevice from '../webmuxd';
import {
BrowserPairingStore,
BrowserUsbMuxClient,
UsbMuxMessageType,
} from "../webmuxd"
test('Module defined', () => {
expect(MobileDevice).toBeDefined();
});
test("Core exports defined", () => {
expect(BrowserPairingStore).toBeDefined()
expect(BrowserUsbMuxClient).toBeDefined()
expect(UsbMuxMessageType.plist).toBe(8)
})

31
src/core/afc-client.ts Normal file
View File

@@ -0,0 +1,31 @@
import { LockdownClient } from "./lockdown-client"
export interface AfcEntry {
path: string
size?: number
type?: string
}
export class AfcClient {
private readonly lockdown: LockdownClient
constructor(lockdown: LockdownClient) {
this.lockdown = lockdown
}
async connect(): Promise<void> {
await this.lockdown.startService("com.apple.afc")
}
listDirectory(_path: string): Promise<AfcEntry[]> {
return Promise.reject(new Error("AFC listDirectory is not implemented yet"))
}
readFile(_path: string): Promise<Uint8Array> {
return Promise.reject(new Error("AFC readFile is not implemented yet"))
}
writeFile(_path: string, _data: Uint8Array): Promise<void> {
return Promise.reject(new Error("AFC writeFile is not implemented yet"))
}
}

View File

@@ -0,0 +1,60 @@
import { AfcClient } from "./afc-client"
import { LockdownClient } from "./lockdown-client"
import { BrowserPairingStore, PairingStore } from "./pairing-store"
import { UsbMuxSession } from "./usbmux-session"
import { UsbMuxTransport } from "./transport"
export interface BrowserUsbMuxClientOptions {
pairingStore?: PairingStore
}
export class BrowserUsbMuxClient {
readonly session: UsbMuxSession
readonly lockdown: LockdownClient
readonly afc: AfcClient
readonly pairingStore: PairingStore
constructor(
transport: UsbMuxTransport,
options: BrowserUsbMuxClientOptions = {},
) {
this.pairingStore = options.pairingStore ?? new BrowserPairingStore()
this.session = new UsbMuxSession(transport)
this.lockdown = new LockdownClient(this.session, this.pairingStore)
this.afc = new AfcClient(this.lockdown)
}
async start(): Promise<void> {
await this.session.start()
}
async stop(): Promise<void> {
await this.session.stop()
}
async listDevices(): Promise<number> {
return await this.session.sendPlistRequest({ messageType: "ListDevices" })
}
async connect(deviceId: number, port: number): Promise<number> {
const deviceIdKey = "DeviceID"
const portNumberKey = "PortNumber"
return await this.session.sendPlistRequest({
messageType: "Connect",
payload: {
[deviceIdKey]: deviceId,
[portNumberKey]: toNetworkByteOrderPort(port),
},
})
}
}
const toNetworkByteOrderPort = (port: number): number => {
if (!Number.isInteger(port) || port < 0 || port > 0xffff) {
throw new RangeError(`Invalid port number: ${String(port)}`)
}
const buffer = new ArrayBuffer(2)
const view = new DataView(buffer)
view.setUint16(0, port, true)
return view.getUint16(0, false)
}

File diff suppressed because it is too large Load Diff

10
src/core/index.ts Normal file
View File

@@ -0,0 +1,10 @@
export * from "./afc-client"
export * from "./browser-usbmux-client"
export * from "./imobiledevice-client"
export * from "./lockdown-client"
export * from "./pairing-store"
export * from "./plist"
export * from "./transport"
export * from "./usbmux-protocol"
export * from "./usbmux-session"
export * from "./webusb-transport"

View File

@@ -0,0 +1,28 @@
import { UsbMuxSession } from "./usbmux-session"
import { PairingStore } from "./pairing-store"
export interface LockdownStartSessionResult {
sessionId: string
}
export class LockdownClient {
private readonly session: UsbMuxSession
private readonly pairingStore: PairingStore
constructor(session: UsbMuxSession, pairingStore: PairingStore) {
this.session = session
this.pairingStore = pairingStore
}
readBuid(): Promise<string> {
return this.pairingStore.getSystemBuid()
}
startSession(_udid: string): Promise<LockdownStartSessionResult> {
return Promise.reject(new Error("Lockdown startSession is not implemented yet"))
}
startService(_serviceName: string): Promise<number> {
return Promise.reject(new Error("Lockdown startService is not implemented yet"))
}
}

89
src/core/pairing-store.ts Normal file
View File

@@ -0,0 +1,89 @@
export interface PairRecordEntry {
udid: string
data: string
}
export interface PairingStore {
getSystemBuid(): Promise<string>
getPairRecord(udid: string): Promise<PairRecordEntry | null>
savePairRecord(record: PairRecordEntry): Promise<void>
deletePairRecord(udid: string): Promise<void>
}
const BUID_KEY = "webmuxd:buid"
const PAIR_PREFIX = "webmuxd:pair:"
export class BrowserPairingStore implements PairingStore {
private readonly inMemory = new Map<string, string>()
getSystemBuid(): Promise<string> {
const existing = this.get(BUID_KEY)
if (existing) {
return Promise.resolve(existing)
}
const created = this.generateBuid()
this.set(BUID_KEY, created)
return Promise.resolve(created)
}
getPairRecord(udid: string): Promise<PairRecordEntry | null> {
const value = this.get(this.toPairKey(udid))
if (!value) {
return Promise.resolve(null)
}
return Promise.resolve({ udid, data: value })
}
savePairRecord(record: PairRecordEntry): Promise<void> {
this.set(this.toPairKey(record.udid), record.data)
return Promise.resolve()
}
deletePairRecord(udid: string): Promise<void> {
this.remove(this.toPairKey(udid))
return Promise.resolve()
}
private toPairKey(udid: string): string {
return `${PAIR_PREFIX}${udid}`
}
private get(key: string): string | null {
if (typeof window !== "undefined" && window.localStorage) {
return window.localStorage.getItem(key)
}
return this.inMemory.get(key) ?? null
}
private set(key: string, value: string): void {
if (typeof window !== "undefined" && window.localStorage) {
window.localStorage.setItem(key, value)
return
}
this.inMemory.set(key, value)
}
private remove(key: string): void {
if (typeof window !== "undefined" && window.localStorage) {
window.localStorage.removeItem(key)
return
}
this.inMemory.delete(key)
}
private generateBuid(): string {
const bytes = new Uint8Array(16)
if (typeof crypto !== "undefined" && crypto.getRandomValues) {
crypto.getRandomValues(bytes)
} else {
for (let i = 0; i < bytes.length; i += 1) {
bytes[i] = Math.floor(Math.random() * 256)
}
}
let out = ""
for (const byte of bytes) {
out += byte.toString(16).padStart(2, "0")
}
return out.toUpperCase()
}
}

89
src/core/plist.ts Normal file
View File

@@ -0,0 +1,89 @@
export type PlistValue =
| string
| number
| boolean
| Uint8Array
| ArrayBuffer
| PlistValue[]
| { [key: string]: PlistValue }
const XML_HEADER =
'<?xml version="1.0" encoding="UTF-8"?>' +
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" ' +
'"http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
export const encodePlistXml = (value: { [key: string]: PlistValue }): Uint8Array => {
const xml = `${XML_HEADER}<plist version="1.0">${encodeValue(value)}</plist>`
return encodeUtf8(xml)
}
const encodeValue = (value: PlistValue): string => {
if (typeof value === "string") {
return `<string>${escapeXml(value)}</string>`
}
if (typeof value === "number") {
if (Number.isInteger(value)) {
return `<integer>${String(value)}</integer>`
}
return `<real>${String(value)}</real>`
}
if (typeof value === "boolean") {
return value ? "<true/>" : "<false/>"
}
if (value instanceof Uint8Array) {
return `<data>${encodeBase64(value)}</data>`
}
if (value instanceof ArrayBuffer) {
return `<data>${encodeBase64(new Uint8Array(value))}</data>`
}
if (Array.isArray(value)) {
let out = "<array>"
for (const item of value) {
out += encodeValue(item)
}
out += "</array>"
return out
}
if (value && typeof value === "object") {
let out = "<dict>"
for (const [key, objectValue] of Object.entries(value)) {
out += `<key>${escapeXml(key)}</key>${encodeValue(objectValue)}`
}
out += "</dict>"
return out
}
throw new Error(`Unsupported plist value type: ${String(value)}`)
}
const escapeXml = (input: string): string => {
return input
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&apos;")
}
const encodeBase64 = (value: Uint8Array): string => {
if (typeof btoa === "function") {
let binary = ""
for (const byte of value) {
binary += String.fromCharCode(byte)
}
return btoa(binary)
}
if (typeof Buffer !== "undefined") {
return Buffer.from(value).toString("base64")
}
throw new Error("No base64 implementation is available in this environment")
}
const encodeUtf8 = (value: string): Uint8Array => {
if (typeof TextEncoder !== "undefined") {
return new TextEncoder().encode(value)
}
if (typeof Buffer !== "undefined") {
return new Uint8Array(Buffer.from(value, "utf8"))
}
throw new Error("No UTF-8 encoder is available in this environment")
}

11
src/core/transport.ts Normal file
View File

@@ -0,0 +1,11 @@
export type DataHandler = (data: ArrayBuffer) => void
export type DisconnectHandler = (reason?: unknown) => void
export interface UsbMuxTransport {
open(): Promise<void>
close(): Promise<void>
send(data: ArrayBuffer): Promise<void>
setDataHandler(handler: DataHandler | null): void
setDisconnectHandler(handler: DisconnectHandler | null): void
readonly isOpen: boolean
}

View File

@@ -0,0 +1,44 @@
/* eslint-disable no-shadow */
export enum UsbMuxMessageType {
result = 1,
connect = 2,
listen = 3,
deviceAdd = 4,
deviceRemove = 5,
devicePaired = 6,
plist = 8,
}
export interface UsbMuxHeader {
length: number
version: number
message: UsbMuxMessageType
tag: number
}
export interface UsbMuxPacket {
header: UsbMuxHeader
payload: ArrayBuffer
}
export const USBMUX_HEADER_SIZE = 16
export const encodeHeader = (header: UsbMuxHeader): ArrayBuffer => {
const buffer = new ArrayBuffer(USBMUX_HEADER_SIZE)
const view = new DataView(buffer)
view.setUint32(0, header.length, true)
view.setUint32(4, header.version, true)
view.setUint32(8, header.message, true)
view.setUint32(12, header.tag, true)
return buffer
}
export const decodeHeader = (data: ArrayBuffer): UsbMuxHeader => {
const view = new DataView(data)
return {
length: view.getUint32(0, true),
version: view.getUint32(4, true),
message: view.getUint32(8, true) as UsbMuxMessageType,
tag: view.getUint32(12, true),
}
}

135
src/core/usbmux-session.ts Normal file
View File

@@ -0,0 +1,135 @@
import {
decodeHeader,
encodeHeader,
USBMUX_HEADER_SIZE,
UsbMuxHeader,
UsbMuxMessageType,
UsbMuxPacket,
} from "./usbmux-protocol"
import { encodePlistXml, PlistValue } from "./plist"
import { UsbMuxTransport } from "./transport"
export interface UsbMuxPlistRequest {
messageType: string
payload?: Record<string, PlistValue>
}
const plistMessageTypeKey = "MessageType"
const USBMUX_MAX_PACKET_SIZE = 0x10000
export class UsbMuxSession {
private readonly transport: UsbMuxTransport
private tagCounter = 1
private onPacketHandler: ((packet: UsbMuxPacket) => void) | null = null
private started = false
private readBuffer = new Uint8Array(0)
constructor(transport: UsbMuxTransport) {
this.transport = transport
}
async start(): Promise<void> {
if (this.started) {
return
}
this.transport.setDataHandler((data) => this.onRawData(data))
await this.transport.open()
this.started = true
}
async stop(): Promise<void> {
if (!this.started) {
return
}
await this.transport.close()
this.started = false
this.readBuffer = new Uint8Array(0)
}
onPacket(handler: ((packet: UsbMuxPacket) => void) | null): void {
this.onPacketHandler = handler
}
async sendPlistRequest(request: UsbMuxPlistRequest): Promise<number> {
const body = encodePlistXml({
...(request.payload ?? {}),
[plistMessageTypeKey]: request.messageType,
})
const tag = this.nextTag()
const header: UsbMuxHeader = {
length: USBMUX_HEADER_SIZE + body.byteLength,
version: 1,
message: UsbMuxMessageType.plist,
tag,
}
const headerBytes = new Uint8Array(encodeHeader(header))
const packet = new Uint8Array(header.length)
packet.set(headerBytes, 0)
packet.set(body, USBMUX_HEADER_SIZE)
await this.transport.send(packet.buffer)
return tag
}
private onRawData(data: ArrayBuffer): void {
const incoming = new Uint8Array(data)
if (incoming.byteLength === 0) {
return
}
this.readBuffer = appendBytes(this.readBuffer, incoming)
this.drainReadBuffer()
}
private nextTag(): number {
const current = this.tagCounter
this.tagCounter += 1
return current
}
private drainReadBuffer(): void {
let offset = 0
while (this.readBuffer.byteLength - offset >= USBMUX_HEADER_SIZE) {
const headerChunk = this.readBuffer.subarray(
offset,
offset + USBMUX_HEADER_SIZE,
)
const headerBytes = headerChunk.buffer.slice(
headerChunk.byteOffset,
headerChunk.byteOffset + USBMUX_HEADER_SIZE,
)
const header = decodeHeader(headerBytes)
if (
header.length < USBMUX_HEADER_SIZE ||
header.length > USBMUX_MAX_PACKET_SIZE
) {
this.readBuffer = new Uint8Array(0)
return
}
if (this.readBuffer.byteLength - offset < header.length) {
break
}
const payloadStart = offset + USBMUX_HEADER_SIZE
const payloadEnd = offset + header.length
const payload = this.readBuffer.slice(payloadStart, payloadEnd)
this.onPacketHandler?.({ header, payload: payload.buffer })
offset = payloadEnd
}
if (offset === 0) {
return
}
if (offset >= this.readBuffer.byteLength) {
this.readBuffer = new Uint8Array(0)
return
}
this.readBuffer = this.readBuffer.slice(offset)
}
}
const appendBytes = (left: Uint8Array, right: Uint8Array): Uint8Array => {
if (left.byteLength === 0) {
return right.slice()
}
const merged = new Uint8Array(left.byteLength + right.byteLength)
merged.set(left, 0)
merged.set(right, left.byteLength)
return merged
}

View File

@@ -0,0 +1,175 @@
import { CONSOLE_LOGGER, Logger, NULL_LOGGER } from "../webmuxd"
import { DataHandler, DisconnectHandler, UsbMuxTransport } from "./transport"
const USBMUX_CLASS = 255
const USBMUX_SUBCLASS = 254
const USBMUX_PROTOCOL = 2
export interface WebUsbTransportOptions {
logger?: Logger
transferSize?: number
}
export class WebUsbTransport implements UsbMuxTransport {
private readonly usbDevice: USBDevice
private readonly transferSize: number
private readonly logger: Logger
private usbInterface: USBInterface | null = null
private usbConfigurationValue: number | null = null
private inputEndpoint: USBEndpoint | null = null
private outputEndpoint: USBEndpoint | null = null
private reading = false
private closing = false
private dataHandler: DataHandler | null = null
private disconnectHandler: DisconnectHandler | null = null
constructor(device: USBDevice, options?: WebUsbTransportOptions) {
this.usbDevice = device
this.transferSize = options?.transferSize ?? 16384
this.logger = options?.logger ?? NULL_LOGGER
}
get isOpen(): boolean {
return this.usbDevice.opened
}
static supported(): boolean {
return "usb" in window.navigator
}
static async requestAppleDevice(
logger: Logger = CONSOLE_LOGGER,
): Promise<WebUsbTransport> {
const device = await navigator.usb.requestDevice({
filters: [{ vendorId: 0x05ac }],
})
logger.log("info", `Selected device ${device.productName ?? "unknown"}`)
return new WebUsbTransport(device, { logger })
}
setDataHandler(handler: DataHandler | null): void {
this.dataHandler = handler
}
setDisconnectHandler(handler: DisconnectHandler | null): void {
this.disconnectHandler = handler
}
async open(): Promise<void> {
this.resolveInterface()
if (!this.usbInterface) {
throw new Error("No usbmux interface found")
}
if (!this.usbDevice.opened) {
await this.usbDevice.open()
}
const selectedConfig = this.usbDevice.configuration?.configurationValue ?? null
if (
this.usbConfigurationValue !== null &&
this.usbConfigurationValue !== selectedConfig
) {
await this.usbDevice.selectConfiguration(this.usbConfigurationValue)
}
if (!this.usbInterface.claimed) {
await this.usbDevice.claimInterface(this.usbInterface.interfaceNumber)
}
this.resolveEndpoints()
if (!this.inputEndpoint || !this.outputEndpoint) {
throw new Error("Failed to resolve usbmux endpoints")
}
this.reading = true
this.closing = false
this.readLoop()
}
async close(): Promise<void> {
if (this.closing) {
return
}
this.closing = true
this.reading = false
if (this.usbInterface?.claimed && this.usbDevice.opened) {
await this.usbDevice.releaseInterface(this.usbInterface.interfaceNumber)
}
if (this.usbDevice.opened) {
await this.usbDevice.close()
}
}
async send(data: ArrayBuffer): Promise<void> {
if (!this.outputEndpoint) {
throw new Error("Output endpoint is not ready")
}
const result = await this.usbDevice.transferOut(
this.outputEndpoint.endpointNumber,
data,
)
if (result.status !== "ok") {
throw new Error(`USB transferOut failed with status ${result.status}`)
}
}
private resolveInterface(): void {
for (const configuration of this.usbDevice.configurations) {
for (const usbInterface of configuration.interfaces) {
for (const alternate of usbInterface.alternates) {
if (
alternate.interfaceClass === USBMUX_CLASS &&
alternate.interfaceSubclass === USBMUX_SUBCLASS &&
alternate.interfaceProtocol === USBMUX_PROTOCOL
) {
this.usbInterface = usbInterface
this.usbConfigurationValue = configuration.configurationValue
return
}
}
}
}
}
private resolveEndpoints(): void {
if (!this.usbInterface) {
return
}
for (const endpoint of this.usbInterface.alternates[0].endpoints) {
if (endpoint.direction === "in") {
this.inputEndpoint = endpoint
} else if (endpoint.direction === "out") {
this.outputEndpoint = endpoint
}
}
}
private readLoop(): void {
if (!this.reading || this.closing || !this.inputEndpoint) {
return
}
this.usbDevice
.transferIn(this.inputEndpoint.endpointNumber, this.transferSize)
.then((result) => {
if (this.closing) {
return
}
if (result.status === "ok" && result.data) {
const bytes = new Uint8Array(
result.data.buffer,
result.data.byteOffset,
result.data.byteLength,
)
this.dataHandler?.(bytes.slice().buffer)
}
this.readLoop()
})
.catch((error) => {
this.logger.log("error", `USB read loop stopped: ${String(error)}`)
this.disconnectHandler?.(error)
})
}
}

225
src/webmuxd.ts Normal file
View File

@@ -0,0 +1,225 @@
const USBMUX_USB_FILTER = [{ vendorId: 0x5ac, productId: 0x12a8 }];
const USBMUX_CLASS = 255;
const USBMUX_SUBCLASS = 254;
const USBMUX_PROTOCOL = 2;
type LogLevel = "debug" | "info" | "warn" | "error"
export interface Logger {
log(level: LogLevel, message: string): void
}
export const NULL_LOGGER = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
log: (level: LogLevel, message: string): void => {
return
}
}
export const CONSOLE_LOGGER = {
log: (level: LogLevel, message: string): void => {
switch (level) {
case "info":
// eslint-disable-next-line no-console
console.log(message)
break
case "warn":
// eslint-disable-next-line no-console
console.warn(message)
break
case "error":
// eslint-disable-next-line no-console
console.error(message)
break
case "debug":
// eslint-disable-next-line no-console
console.debug(message)
break
default:
// eslint-disable-next-line no-console
console.error(`Unknown log level ${level}: ${message}`)
}
}
}
export default class MobileDevice {
static logger: Logger = NULL_LOGGER
usbDevice: USBDevice;
usbConfiguration: USBConfiguration | null = null
usbInterface: USBInterface | null = null
private closing = false
private readInterval: number | null = null
usbInputEndpoint: USBEndpoint | null = null
usbOutputEndpoint: USBEndpoint | null = null
inputTransfer: Promise<USBInTransferResult> | null = null
public handleData: ((data: ArrayBuffer) => void) | null = null
constructor(device: USBDevice) {
this.usbDevice = device;
}
static supported(): boolean {
return 'usb' in window.navigator;
}
static async selectDevice(): Promise<MobileDevice> {
const device = await navigator.usb.requestDevice({ filters: USBMUX_USB_FILTER });
return new MobileDevice(device);
}
static async getDevices(): Promise<MobileDevice[]> {
const devices = await navigator.usb.getDevices();
return devices.map((device) => {
return new MobileDevice(device);
});
}
get name(): string {
return this.usbDevice.productName as string;
}
get serialNumber(): string {
return this.usbDevice.serialNumber as string;
}
async close(): Promise<void> {
if (!this.closing && this.readInterval) {
window.clearInterval(this.readInterval);
}
this.closing = true;
if (this.usbDevice && this.usbDevice.opened) {
if (this.usbInterface && this.usbInterface.claimed) {
MobileDevice.logger.log("info", `Closing interface ${this.usbInterface.interfaceNumber} for ${this.usbDevice.serialNumber}`);
await this.usbDevice.releaseInterface(this.usbInterface.interfaceNumber);
}
await this.usbDevice.selectConfiguration(1);
try {
MobileDevice.logger.log("info", `Resetting device ${this.usbDevice.serialNumber}`);
await this.usbDevice.reset();
} finally {
MobileDevice.logger.log("info", `Closing device ${this.usbDevice.serialNumber}`);
await this.usbDevice.close();
MobileDevice.logger.log("info", `Closed ${this.serialNumber}`);
}
}
}
async open(): Promise<void> {
try {
for (const configuration of this.usbDevice.configurations) {
for (const usbInterface of configuration.interfaces) {
MobileDevice.logger.log("debug", `Interface ${usbInterface.interfaceNumber} (Claimed: ${usbInterface.claimed})`)
for (const alternate of usbInterface.alternates) {
MobileDevice.logger.log("debug", `\tAlternate ${alternate.alternateSetting} ${alternate.interfaceName} Class ${alternate.interfaceClass} Subclass ${alternate.interfaceSubclass} Protocol ${alternate.interfaceProtocol}`)
if (
alternate.interfaceClass === USBMUX_CLASS &&
alternate.interfaceSubclass === USBMUX_SUBCLASS &&
alternate.interfaceProtocol === USBMUX_PROTOCOL
) {
this.usbInterface = usbInterface;
this.usbConfiguration = configuration;
}
}
}
}
if (this.usbConfiguration && this.usbInterface) {
MobileDevice.logger.log("info", `Opening device ${this.usbDevice.serialNumber}`);
await this.usbDevice.open();
if (this.usbDevice.configuration?.configurationValue !== this.usbConfiguration.configurationValue) {
MobileDevice.logger.log("info",
`Selecting Configuration ${this.usbConfiguration.configurationValue} from ${this.usbDevice.configuration?.configurationValue}`,
);
await this.usbDevice.selectConfiguration(this.usbConfiguration.configurationValue);
}
MobileDevice.logger.log("info", `Claiming Interface ${this.usbInterface.interfaceNumber}`);
await this.usbDevice.claimInterface(this.usbInterface.interfaceNumber);
for (const endpoint of this.usbInterface.alternates[0].endpoints) {
MobileDevice.logger.log("info", `Endpoint ${endpoint.endpointNumber} ${endpoint.direction}`);
if (endpoint.direction === 'in') {
this.usbInputEndpoint = endpoint;
}
if (endpoint.direction === 'out') {
this.usbOutputEndpoint = endpoint;
}
}
} else {
MobileDevice.logger.log("error", `No configuration ${this.usbConfiguration} or interface ${this.usbInterface}`);
}
this.readInterval = window.setInterval(() => {
this.deviceReader();
}, 1000);
} catch (e) {
if (typeof e === 'string') {
MobileDevice.logger.log("error", e);
}
else if (e instanceof Error) {
MobileDevice.logger.log("error", e.message)
}
}
}
private deviceReader() {
if (!this || !this.usbDevice || !this.usbDevice.opened || !this.usbInterface) {
MobileDevice.logger.log("info", 'deviceReader not in ready state');
return;
}
if (this.inputTransfer && !this.closing) {
return;
}
MobileDevice.logger.log("info", 'MobileDevice deviceReader loop');
if (this.usbInputEndpoint === null) {
throw new Error('No input endpoint');
}
const inputEndpoint = this.usbInputEndpoint.endpointNumber;
this.inputTransfer = this.usbDevice.transferIn(inputEndpoint, 4096);
this.inputTransfer
.then((result) => {
MobileDevice.logger.log("info", `Received USB data ${result.data?.byteLength} status ${result.status}`);
if (this.handleData && result.data) {
this.handleData(result.data.buffer);
}
this.inputTransfer = null;
this.deviceReader();
})
.catch((reason) => {
MobileDevice.logger.log("error", `InputTransfer exception: ${reason}`);
});
}
async sendData(data: ArrayBuffer): Promise<USBOutTransferResult | null> {
const outputEndpoint = this.usbOutputEndpoint?.endpointNumber;
if (outputEndpoint !== undefined) {
MobileDevice.logger.log("info", `Outputting Data to Device on ${outputEndpoint}`);
return await this.usbDevice.transferOut(outputEndpoint, data);
} else {
MobileDevice.logger.log("info", `Undefined output interface ${outputEndpoint}`);
}
return null;
}
}
export * from "./core"

1
tls/openssl-wasm/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target/

297
tls/openssl-wasm/Cargo.lock generated Normal file
View File

@@ -0,0 +1,297 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "bitflags"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
[[package]]
name = "bumpalo"
version = "3.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
[[package]]
name = "cc"
version = "1.2.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2"
dependencies = [
"find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "itoa"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]]
name = "js-sys"
version = "0.3.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.182"
[[package]]
name = "memchr"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "openssl"
version = "0.10.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
dependencies = [
"bitflags",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "openssl-sys"
version = "0.9.111"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "openssl-wasm"
version = "0.1.0"
dependencies = [
"cc",
"js-sys",
"openssl",
"openssl-sys",
"serde",
"serde_json",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "pkg-config"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "wasm-bindgen"
version = "0.2.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16"
dependencies = [
"unicode-ident",
]
[[package]]
name = "web-sys"
version = "0.3.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"

View File

@@ -0,0 +1,23 @@
[package]
name = "openssl-wasm"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib", "rlib"]
[build-dependencies]
cc = "1"
[dependencies]
js-sys = "0.3"
openssl = "0.10.75"
openssl-sys = { path = "vendor/openssl-sys" }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
wasm-bindgen = "0.2.100"
web-sys = { version = "0.3", features = ["Window", "Crypto"] }
[patch.crates-io]
openssl-sys = { path = "vendor/openssl-sys" }
libc = { path = "vendor/libc-shim" }

View File

@@ -0,0 +1,6 @@
fn main() {
cc::Build::new()
.file("src/c_shim/vsnprintf_shim.c")
.flag_if_supported("-std=c99")
.compile("vsnprintf_shim");
}

35
tls/openssl-wasm/build.sh Executable file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$ROOT_DIR"
OPENSSL_ROOT="/Users/libr/Desktop/Life/browser-apple/openssl-wasm/precompiled"
LLVM_BIN="/opt/homebrew/opt/llvm/bin"
export OPENSSL_NO_VENDOR=1
export OPENSSL_STATIC=1
export OPENSSL_DIR="$OPENSSL_ROOT"
export OPENSSL_LIB_DIR="$OPENSSL_ROOT/lib"
export OPENSSL_INCLUDE_DIR="$OPENSSL_ROOT/include"
export OPENSSL_LIBS="ssl:crypto"
export CC_wasm32_unknown_unknown="$LLVM_BIN/clang --target=wasm32-unknown-unknown"
export AR_wasm32_unknown_unknown="$LLVM_BIN/llvm-ar"
export RANLIB_wasm32_unknown_unknown="$LLVM_BIN/llvm-ranlib"
echo "[1/2] Building wasm32-unknown-unknown with openssl-rs..."
cargo build --release --target wasm32-unknown-unknown
if command -v wasm-bindgen >/dev/null 2>&1; then
echo "[2/2] Generating JS bindings with wasm-bindgen..."
mkdir -p pkg
wasm-bindgen \
target/wasm32-unknown-unknown/release/openssl_wasm.wasm \
--out-dir pkg \
--target web
echo "Done: pkg/ generated."
else
echo "[2/2] wasm-bindgen CLI not found; skipped JS binding generation."
echo "Install via: cargo install wasm-bindgen-cli"
fi

103
tls/openssl-wasm/pkg/openssl_wasm.d.ts vendored Normal file
View File

@@ -0,0 +1,103 @@
/* tslint:disable */
/* eslint-disable */
export class OpensslClient {
free(): void;
[Symbol.dispose](): void;
feed_tls(data: Uint8Array): void;
is_handshaking(): boolean;
constructor(_server_name: string, _ca_cert_pem: string, client_cert_pem: string, client_key_pem: string);
take_plain_out(): Uint8Array;
take_tls_out(): Uint8Array;
write_plaintext(data: Uint8Array): void;
}
export function debug_runtime_stats(): string;
export function libimobiledevice_generate_pair_record(device_public_key: Uint8Array, host_id: string, system_buid: string): string;
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
export interface InitOutput {
readonly memory: WebAssembly.Memory;
readonly SSL_add_dir_cert_subjects_to_stack: (a: number, b: number) => number;
readonly __cxa_atexit: (a: number, b: number, c: number) => number;
readonly __wbg_opensslclient_free: (a: number, b: number) => void;
readonly abort: () => void;
readonly arc4random_buf: (a: number, b: number) => void;
readonly atoi: (a: number) => number;
readonly calloc: (a: number, b: number) => number;
readonly clock_gettime: (a: number, b: number) => number;
readonly close: (a: number) => number;
readonly closedir: (a: number) => number;
readonly debug_runtime_stats: () => [number, number];
readonly free: (a: number) => void;
readonly fstat: (a: number, b: number) => number;
readonly getentropy: (a: number, b: number) => number;
readonly getenv: (a: number) => number;
readonly getpid: () => number;
readonly gettimeofday: (a: number, b: number) => number;
readonly libimobiledevice_generate_pair_record: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number, number, number];
readonly malloc: (a: number) => number;
readonly memchr: (a: number, b: number, c: number) => number;
readonly open: (a: number, b: number, c: number) => number;
readonly opendir: (a: number) => number;
readonly opensslclient_feed_tls: (a: number, b: number, c: number) => [number, number];
readonly opensslclient_is_handshaking: (a: number) => number;
readonly opensslclient_new: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => [number, number, number];
readonly opensslclient_take_plain_out: (a: number) => [number, number];
readonly opensslclient_take_tls_out: (a: number) => [number, number];
readonly opensslclient_write_plaintext: (a: number, b: number, c: number) => [number, number];
readonly posix_memalign: (a: number, b: number, c: number) => number;
readonly qsort: (a: number, b: number, c: number, d: number) => void;
readonly read: (a: number, b: number, c: number) => number;
readonly readdir: (a: number) => number;
readonly realloc: (a: number, b: number) => number;
readonly sscanf: (a: number, b: number, c: number) => number;
readonly stat: (a: number, b: number) => number;
readonly strchr: (a: number, b: number) => number;
readonly strcmp: (a: number, b: number) => number;
readonly strcpy: (a: number, b: number) => number;
readonly strcspn: (a: number, b: number) => number;
readonly strerror: (a: number) => number;
readonly strncmp: (a: number, b: number, c: number) => number;
readonly strncpy: (a: number, b: number, c: number) => number;
readonly strpbrk: (a: number, b: number) => number;
readonly strrchr: (a: number, b: number) => number;
readonly strspn: (a: number, b: number) => number;
readonly strstr: (a: number, b: number) => number;
readonly strtol: (a: number, b: number, c: number) => number;
readonly strtoul: (a: number, b: number, c: number) => number;
readonly time: (a: number) => bigint;
readonly tolower: (a: number) => number;
readonly __wbindgen_exn_store_command_export: (a: number) => void;
readonly __externref_table_alloc_command_export: () => number;
readonly __wbindgen_externrefs: WebAssembly.Table;
readonly __wbindgen_free_command_export: (a: number, b: number, c: number) => void;
readonly __wbindgen_malloc_command_export: (a: number, b: number) => number;
readonly __wbindgen_realloc_command_export: (a: number, b: number, c: number, d: number) => number;
readonly __externref_table_dealloc_command_export: (a: number) => void;
readonly __wbindgen_start: () => void;
}
export type SyncInitInput = BufferSource | WebAssembly.Module;
/**
* Instantiates the given `module`, which can either be bytes or
* a precompiled `WebAssembly.Module`.
*
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
*
* @returns {InitOutput}
*/
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
/**
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
* for everything else, calls `WebAssembly.instantiate` directly.
*
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
*
* @returns {Promise<InitOutput>}
*/
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;

View File

@@ -0,0 +1,409 @@
/* @ts-self-types="./openssl_wasm.d.ts" */
export class OpensslClient {
__destroy_into_raw() {
const ptr = this.__wbg_ptr;
this.__wbg_ptr = 0;
OpensslClientFinalization.unregister(this);
return ptr;
}
free() {
const ptr = this.__destroy_into_raw();
wasm.__wbg_opensslclient_free(ptr, 0);
}
/**
* @param {Uint8Array} data
*/
feed_tls(data) {
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc_command_export);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.opensslclient_feed_tls(this.__wbg_ptr, ptr0, len0);
if (ret[1]) {
throw takeFromExternrefTable0(ret[0]);
}
}
/**
* @returns {boolean}
*/
is_handshaking() {
const ret = wasm.opensslclient_is_handshaking(this.__wbg_ptr);
return ret !== 0;
}
/**
* @param {string} _server_name
* @param {string} _ca_cert_pem
* @param {string} client_cert_pem
* @param {string} client_key_pem
*/
constructor(_server_name, _ca_cert_pem, client_cert_pem, client_key_pem) {
const ptr0 = passStringToWasm0(_server_name, wasm.__wbindgen_malloc_command_export, wasm.__wbindgen_realloc_command_export);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(_ca_cert_pem, wasm.__wbindgen_malloc_command_export, wasm.__wbindgen_realloc_command_export);
const len1 = WASM_VECTOR_LEN;
const ptr2 = passStringToWasm0(client_cert_pem, wasm.__wbindgen_malloc_command_export, wasm.__wbindgen_realloc_command_export);
const len2 = WASM_VECTOR_LEN;
const ptr3 = passStringToWasm0(client_key_pem, wasm.__wbindgen_malloc_command_export, wasm.__wbindgen_realloc_command_export);
const len3 = WASM_VECTOR_LEN;
const ret = wasm.opensslclient_new(ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
if (ret[2]) {
throw takeFromExternrefTable0(ret[1]);
}
this.__wbg_ptr = ret[0] >>> 0;
OpensslClientFinalization.register(this, this.__wbg_ptr, this);
return this;
}
/**
* @returns {Uint8Array}
*/
take_plain_out() {
const ret = wasm.opensslclient_take_plain_out(this.__wbg_ptr);
var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
wasm.__wbindgen_free_command_export(ret[0], ret[1] * 1, 1);
return v1;
}
/**
* @returns {Uint8Array}
*/
take_tls_out() {
const ret = wasm.opensslclient_take_tls_out(this.__wbg_ptr);
var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
wasm.__wbindgen_free_command_export(ret[0], ret[1] * 1, 1);
return v1;
}
/**
* @param {Uint8Array} data
*/
write_plaintext(data) {
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc_command_export);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.opensslclient_write_plaintext(this.__wbg_ptr, ptr0, len0);
if (ret[1]) {
throw takeFromExternrefTable0(ret[0]);
}
}
}
if (Symbol.dispose) OpensslClient.prototype[Symbol.dispose] = OpensslClient.prototype.free;
/**
* @returns {string}
*/
export function debug_runtime_stats() {
let deferred1_0;
let deferred1_1;
try {
const ret = wasm.debug_runtime_stats();
deferred1_0 = ret[0];
deferred1_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
} finally {
wasm.__wbindgen_free_command_export(deferred1_0, deferred1_1, 1);
}
}
/**
* @param {Uint8Array} device_public_key
* @param {string} host_id
* @param {string} system_buid
* @returns {string}
*/
export function libimobiledevice_generate_pair_record(device_public_key, host_id, system_buid) {
let deferred5_0;
let deferred5_1;
try {
const ptr0 = passArray8ToWasm0(device_public_key, wasm.__wbindgen_malloc_command_export);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(host_id, wasm.__wbindgen_malloc_command_export, wasm.__wbindgen_realloc_command_export);
const len1 = WASM_VECTOR_LEN;
const ptr2 = passStringToWasm0(system_buid, wasm.__wbindgen_malloc_command_export, wasm.__wbindgen_realloc_command_export);
const len2 = WASM_VECTOR_LEN;
const ret = wasm.libimobiledevice_generate_pair_record(ptr0, len0, ptr1, len1, ptr2, len2);
var ptr4 = ret[0];
var len4 = ret[1];
if (ret[3]) {
ptr4 = 0; len4 = 0;
throw takeFromExternrefTable0(ret[2]);
}
deferred5_0 = ptr4;
deferred5_1 = len4;
return getStringFromWasm0(ptr4, len4);
} finally {
wasm.__wbindgen_free_command_export(deferred5_0, deferred5_1, 1);
}
}
function __wbg_get_imports() {
const import0 = {
__proto__: null,
__wbg___wbindgen_is_undefined_52709e72fb9f179c: function(arg0) {
const ret = arg0 === undefined;
return ret;
},
__wbg___wbindgen_throw_6ddd609b62940d55: function(arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
},
__wbg_crypto_ed4c4da5b2e2eae1: function() { return handleError(function (arg0) {
const ret = arg0.crypto;
return ret;
}, arguments); },
__wbg_getRandomValues_227324ee0d4080c2: function() { return handleError(function (arg0, arg1, arg2) {
const ret = arg0.getRandomValues(getArrayU8FromWasm0(arg1, arg2));
return ret;
}, arguments); },
__wbg_instanceof_Window_23e677d2c6843922: function(arg0) {
let result;
try {
result = arg0 instanceof Window;
} catch (_) {
result = false;
}
const ret = result;
return ret;
},
__wbg_static_accessor_GLOBAL_8adb955bd33fac2f: function() {
const ret = typeof global === 'undefined' ? null : global;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
},
__wbg_static_accessor_GLOBAL_THIS_ad356e0db91c7913: function() {
const ret = typeof globalThis === 'undefined' ? null : globalThis;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
},
__wbg_static_accessor_SELF_f207c857566db248: function() {
const ret = typeof self === 'undefined' ? null : self;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
},
__wbg_static_accessor_WINDOW_bb9f1ba69d61b386: function() {
const ret = typeof window === 'undefined' ? null : window;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
},
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
// Cast intrinsic for `Ref(String) -> Externref`.
const ret = getStringFromWasm0(arg0, arg1);
return ret;
},
__wbindgen_init_externref_table: function() {
const table = wasm.__wbindgen_externrefs;
const offset = table.grow(4);
table.set(0, undefined);
table.set(offset + 0, undefined);
table.set(offset + 1, null);
table.set(offset + 2, true);
table.set(offset + 3, false);
},
};
return {
__proto__: null,
"./openssl_wasm_bg.js": import0,
};
}
const OpensslClientFinalization = (typeof FinalizationRegistry === 'undefined')
? { register: () => {}, unregister: () => {} }
: new FinalizationRegistry(ptr => wasm.__wbg_opensslclient_free(ptr >>> 0, 1));
function addToExternrefTable0(obj) {
const idx = wasm.__externref_table_alloc_command_export();
wasm.__wbindgen_externrefs.set(idx, obj);
return idx;
}
function getArrayU8FromWasm0(ptr, len) {
ptr = ptr >>> 0;
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
}
function getStringFromWasm0(ptr, len) {
ptr = ptr >>> 0;
return decodeText(ptr, len);
}
let cachedUint8ArrayMemory0 = null;
function getUint8ArrayMemory0() {
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
}
return cachedUint8ArrayMemory0;
}
function handleError(f, args) {
try {
return f.apply(this, args);
} catch (e) {
const idx = addToExternrefTable0(e);
wasm.__wbindgen_exn_store_command_export(idx);
}
}
function isLikeNone(x) {
return x === undefined || x === null;
}
function passArray8ToWasm0(arg, malloc) {
const ptr = malloc(arg.length * 1, 1) >>> 0;
getUint8ArrayMemory0().set(arg, ptr / 1);
WASM_VECTOR_LEN = arg.length;
return ptr;
}
function passStringToWasm0(arg, malloc, realloc) {
if (realloc === undefined) {
const buf = cachedTextEncoder.encode(arg);
const ptr = malloc(buf.length, 1) >>> 0;
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
WASM_VECTOR_LEN = buf.length;
return ptr;
}
let len = arg.length;
let ptr = malloc(len, 1) >>> 0;
const mem = getUint8ArrayMemory0();
let offset = 0;
for (; offset < len; offset++) {
const code = arg.charCodeAt(offset);
if (code > 0x7F) break;
mem[ptr + offset] = code;
}
if (offset !== len) {
if (offset !== 0) {
arg = arg.slice(offset);
}
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
const ret = cachedTextEncoder.encodeInto(arg, view);
offset += ret.written;
ptr = realloc(ptr, len, offset, 1) >>> 0;
}
WASM_VECTOR_LEN = offset;
return ptr;
}
function takeFromExternrefTable0(idx) {
const value = wasm.__wbindgen_externrefs.get(idx);
wasm.__externref_table_dealloc_command_export(idx);
return value;
}
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
cachedTextDecoder.decode();
const MAX_SAFARI_DECODE_BYTES = 2146435072;
let numBytesDecoded = 0;
function decodeText(ptr, len) {
numBytesDecoded += len;
if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
cachedTextDecoder.decode();
numBytesDecoded = len;
}
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
}
const cachedTextEncoder = new TextEncoder();
if (!('encodeInto' in cachedTextEncoder)) {
cachedTextEncoder.encodeInto = function (arg, view) {
const buf = cachedTextEncoder.encode(arg);
view.set(buf);
return {
read: arg.length,
written: buf.length
};
};
}
let WASM_VECTOR_LEN = 0;
let wasmModule, wasm;
function __wbg_finalize_init(instance, module) {
wasm = instance.exports;
wasmModule = module;
cachedUint8ArrayMemory0 = null;
wasm.__wbindgen_start();
return wasm;
}
async function __wbg_load(module, imports) {
if (typeof Response === 'function' && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === 'function') {
try {
return await WebAssembly.instantiateStreaming(module, imports);
} catch (e) {
const validResponse = module.ok && expectedResponseType(module.type);
if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
} else { throw e; }
}
}
const bytes = await module.arrayBuffer();
return await WebAssembly.instantiate(bytes, imports);
} else {
const instance = await WebAssembly.instantiate(module, imports);
if (instance instanceof WebAssembly.Instance) {
return { instance, module };
} else {
return instance;
}
}
function expectedResponseType(type) {
switch (type) {
case 'basic': case 'cors': case 'default': return true;
}
return false;
}
}
function initSync(module) {
if (wasm !== undefined) return wasm;
if (module !== undefined) {
if (Object.getPrototypeOf(module) === Object.prototype) {
({module} = module)
} else {
console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
}
}
const imports = __wbg_get_imports();
if (!(module instanceof WebAssembly.Module)) {
module = new WebAssembly.Module(module);
}
const instance = new WebAssembly.Instance(module, imports);
return __wbg_finalize_init(instance, module);
}
async function __wbg_init(module_or_path) {
if (wasm !== undefined) return wasm;
if (module_or_path !== undefined) {
if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
({module_or_path} = module_or_path)
} else {
console.warn('using deprecated parameters for the initialization function; pass a single object instead')
}
}
if (module_or_path === undefined) {
module_or_path = new URL('openssl_wasm_bg.wasm', import.meta.url);
}
const imports = __wbg_get_imports();
if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
module_or_path = fetch(module_or_path);
}
const { instance, module } = await __wbg_load(await module_or_path, imports);
return __wbg_finalize_init(instance, module);
}
export { initSync, __wbg_init as default };

Binary file not shown.

View File

@@ -0,0 +1,61 @@
/* tslint:disable */
/* eslint-disable */
export const memory: WebAssembly.Memory;
export const SSL_add_dir_cert_subjects_to_stack: (a: number, b: number) => number;
export const __cxa_atexit: (a: number, b: number, c: number) => number;
export const __wbg_opensslclient_free: (a: number, b: number) => void;
export const abort: () => void;
export const arc4random_buf: (a: number, b: number) => void;
export const atoi: (a: number) => number;
export const calloc: (a: number, b: number) => number;
export const clock_gettime: (a: number, b: number) => number;
export const close: (a: number) => number;
export const closedir: (a: number) => number;
export const debug_runtime_stats: () => [number, number];
export const free: (a: number) => void;
export const fstat: (a: number, b: number) => number;
export const getentropy: (a: number, b: number) => number;
export const getenv: (a: number) => number;
export const getpid: () => number;
export const gettimeofday: (a: number, b: number) => number;
export const libimobiledevice_generate_pair_record: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number, number, number];
export const malloc: (a: number) => number;
export const memchr: (a: number, b: number, c: number) => number;
export const open: (a: number, b: number, c: number) => number;
export const opendir: (a: number) => number;
export const opensslclient_feed_tls: (a: number, b: number, c: number) => [number, number];
export const opensslclient_is_handshaking: (a: number) => number;
export const opensslclient_new: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => [number, number, number];
export const opensslclient_take_plain_out: (a: number) => [number, number];
export const opensslclient_take_tls_out: (a: number) => [number, number];
export const opensslclient_write_plaintext: (a: number, b: number, c: number) => [number, number];
export const posix_memalign: (a: number, b: number, c: number) => number;
export const qsort: (a: number, b: number, c: number, d: number) => void;
export const read: (a: number, b: number, c: number) => number;
export const readdir: (a: number) => number;
export const realloc: (a: number, b: number) => number;
export const sscanf: (a: number, b: number, c: number) => number;
export const stat: (a: number, b: number) => number;
export const strchr: (a: number, b: number) => number;
export const strcmp: (a: number, b: number) => number;
export const strcpy: (a: number, b: number) => number;
export const strcspn: (a: number, b: number) => number;
export const strerror: (a: number) => number;
export const strncmp: (a: number, b: number, c: number) => number;
export const strncpy: (a: number, b: number, c: number) => number;
export const strpbrk: (a: number, b: number) => number;
export const strrchr: (a: number, b: number) => number;
export const strspn: (a: number, b: number) => number;
export const strstr: (a: number, b: number) => number;
export const strtol: (a: number, b: number, c: number) => number;
export const strtoul: (a: number, b: number, c: number) => number;
export const time: (a: number) => bigint;
export const tolower: (a: number) => number;
export const __wbindgen_exn_store_command_export: (a: number) => void;
export const __externref_table_alloc_command_export: () => number;
export const __wbindgen_externrefs: WebAssembly.Table;
export const __wbindgen_free_command_export: (a: number, b: number, c: number) => void;
export const __wbindgen_malloc_command_export: (a: number, b: number) => number;
export const __wbindgen_realloc_command_export: (a: number, b: number, c: number, d: number) => number;
export const __externref_table_dealloc_command_export: (a: number) => void;
export const __wbindgen_start: () => void;

View File

@@ -0,0 +1,223 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
typedef enum {
LEN_DEFAULT = 0,
LEN_HH,
LEN_H,
LEN_L,
LEN_LL,
LEN_Z,
LEN_T,
LEN_J
} length_mod_t;
static void out_char(char *dst, size_t size, size_t *written, char ch) {
if (*written + 1 < size && dst != NULL) {
dst[*written] = ch;
}
*written += 1;
}
static void out_str(char *dst, size_t size, size_t *written, const char *str) {
if (!str) {
str = "(null)";
}
while (*str) {
out_char(dst, size, written, *str++);
}
}
static void out_uint(
char *dst,
size_t size,
size_t *written,
unsigned long long value,
unsigned base,
int uppercase
) {
char buf[64];
size_t i = 0;
const char *digits = uppercase ? "0123456789ABCDEF" : "0123456789abcdef";
if (base < 2 || base > 16) {
return;
}
if (value == 0) {
out_char(dst, size, written, '0');
return;
}
while (value != 0 && i < sizeof(buf)) {
buf[i++] = digits[value % base];
value /= base;
}
while (i > 0) {
out_char(dst, size, written, buf[--i]);
}
}
static long long read_signed_arg(va_list *ap, length_mod_t len) {
switch (len) {
case LEN_HH: return (signed char)va_arg(*ap, int);
case LEN_H: return (short)va_arg(*ap, int);
case LEN_L: return va_arg(*ap, long);
case LEN_LL: return va_arg(*ap, long long);
case LEN_Z: return (long long)va_arg(*ap, size_t);
case LEN_T: return (long long)va_arg(*ap, ptrdiff_t);
case LEN_J: return (long long)va_arg(*ap, intmax_t);
case LEN_DEFAULT:
default:
return va_arg(*ap, int);
}
}
static unsigned long long read_unsigned_arg(va_list *ap, length_mod_t len) {
switch (len) {
case LEN_HH: return (unsigned char)va_arg(*ap, unsigned int);
case LEN_H: return (unsigned short)va_arg(*ap, unsigned int);
case LEN_L: return va_arg(*ap, unsigned long);
case LEN_LL: return va_arg(*ap, unsigned long long);
case LEN_Z: return (unsigned long long)va_arg(*ap, size_t);
case LEN_T: return (unsigned long long)va_arg(*ap, ptrdiff_t);
case LEN_J: return (unsigned long long)va_arg(*ap, uintmax_t);
case LEN_DEFAULT:
default:
return va_arg(*ap, unsigned int);
}
}
int vsnprintf(char *dst, size_t size, const char *format, va_list ap) {
size_t written = 0;
if (!format) {
if (dst != NULL && size > 0) {
dst[0] = '\0';
}
return 0;
}
while (*format) {
if (*format != '%') {
out_char(dst, size, &written, *format++);
continue;
}
format++;
if (*format == '%') {
out_char(dst, size, &written, '%');
format++;
continue;
}
while (*format == '-' || *format == '+' || *format == ' ' || *format == '#' || *format == '0') {
format++;
}
if (*format == '*') {
(void)va_arg(ap, int);
format++;
} else {
while (*format >= '0' && *format <= '9') {
format++;
}
}
if (*format == '.') {
format++;
if (*format == '*') {
(void)va_arg(ap, int);
format++;
} else {
while (*format >= '0' && *format <= '9') {
format++;
}
}
}
length_mod_t len = LEN_DEFAULT;
if (*format == 'h') {
format++;
len = (*format == 'h') ? (format++, LEN_HH) : LEN_H;
} else if (*format == 'l') {
format++;
len = (*format == 'l') ? (format++, LEN_LL) : LEN_L;
} else if (*format == 'z') {
len = LEN_Z;
format++;
} else if (*format == 't') {
len = LEN_T;
format++;
} else if (*format == 'j') {
len = LEN_J;
format++;
}
switch (*format) {
case 'c': {
int ch = va_arg(ap, int);
out_char(dst, size, &written, (char)ch);
break;
}
case 's': {
const char *str = va_arg(ap, const char *);
out_str(dst, size, &written, str);
break;
}
case 'd':
case 'i': {
long long value = read_signed_arg(&ap, len);
unsigned long long mag = (value < 0)
? (unsigned long long)(-(value + 1)) + 1ULL
: (unsigned long long)value;
if (value < 0) {
out_char(dst, size, &written, '-');
}
out_uint(dst, size, &written, mag, 10, 0);
break;
}
case 'u': {
unsigned long long value = read_unsigned_arg(&ap, len);
out_uint(dst, size, &written, value, 10, 0);
break;
}
case 'x': {
unsigned long long value = read_unsigned_arg(&ap, len);
out_uint(dst, size, &written, value, 16, 0);
break;
}
case 'X': {
unsigned long long value = read_unsigned_arg(&ap, len);
out_uint(dst, size, &written, value, 16, 1);
break;
}
case 'o': {
unsigned long long value = read_unsigned_arg(&ap, len);
out_uint(dst, size, &written, value, 8, 0);
break;
}
case 'p': {
uintptr_t value = (uintptr_t)va_arg(ap, void *);
out_str(dst, size, &written, "0x");
out_uint(dst, size, &written, (unsigned long long)value, 16, 0);
break;
}
default: {
out_char(dst, size, &written, '%');
if (*format) {
out_char(dst, size, &written, *format);
}
break;
}
}
if (*format) {
format++;
}
}
if (dst != NULL && size > 0) {
size_t end = (written < size) ? written : (size - 1);
dst[end] = '\0';
}
return (int)written;
}

1229
tls/openssl-wasm/src/lib.rs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
[package]
name = "libc"
version = "0.2.182"
edition = "2021"
[lib]
name = "libc"
path = "src/lib.rs"

View File

@@ -0,0 +1,44 @@
#![no_std]
#![allow(non_camel_case_types)]
pub use core::ffi::{
c_char, c_double, c_float, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint,
c_ulong, c_ulonglong, c_ushort, c_void,
};
pub type intptr_t = isize;
pub type uintptr_t = usize;
pub type ptrdiff_t = isize;
pub type size_t = usize;
pub type ssize_t = isize;
pub type time_t = i64;
pub type suseconds_t = i64;
#[repr(C)]
pub struct FILE {
_private: [u8; 0],
}
#[repr(C)]
pub struct tm {
_private: [u8; 0],
}
#[repr(C)]
pub struct timeval {
pub tv_sec: time_t,
pub tv_usec: suseconds_t,
}
pub unsafe fn pthread_self() -> usize {
1
}
pub unsafe fn strlen(mut ptr: *const c_char) -> size_t {
let mut len: size_t = 0;
while !ptr.is_null() && *ptr != 0 {
len += 1;
ptr = ptr.add(1);
}
len
}

View File

@@ -0,0 +1 @@
{"v":1}

View File

@@ -0,0 +1,6 @@
{
"git": {
"sha1": "09b90d036ec5341deefb7fce86748e176379d01a"
},
"path_in_vcs": "openssl-sys"
}

View File

@@ -0,0 +1,758 @@
# Change Log
## [Unreleased]
## [v0.9.111] - 2025-11-07
### Added
* Added bindings to `EVP_MAC` APIs.
* Added bindings to `ASN1_GENERALIZEDTIME_new` and `ASN1_GENERALIZEDTIME_set_string`.
## [v0.9.110] - 2025-10-14
### Added
* Added support for LibreSSL 4.2.0.
* Added bindings to many OpenSSL APIs.
### Changed
* Bumped bindgen to 0.72.0.
* Bumped MSRV to 1.70.
### Fixed
* Fixed missing `__off_t` on NetBSD 10.
* Fixed building with `OPENSSL_NO_COMP`.
* Fixed building with `OPENSSL_NO_SRTP`.
* Fixed finding OpenSSL on AIX.
### Removed
* Removed support for OpenSSL <1.0.2.
* Removed support for LibreSSL <3.5.
## [v0.9.109] - 2025-05-28
### Fixed
* Fixed building with `vcpkg`, a statically linked OpenSSL, and rust 1.87.0.
* Fixed building on the latest BoringSSL.
## [v0.9.108] - 2025-04-30
### Added
* Added support for LibreSSL 4.1.x.
## [v0.9.107] - 2025-04-04
### Added
* Support for building with AWS-LC.
## [v0.9.106] - 2025-02-15
### Added
* Support building with `OPENSSL_NO_RC2`.
* Exposed `EVP_rc2_cbc` and `EVP_rc2_40_cbc`.
## [v0.9.105] - 2025-02-02
### Added
* Added `DTLS_server_method` and `DTLS_client_method`.
## [v0.9.104] - 2024-10-15
### Added
* Added support for LibreSSL 4.0.x.
* Added `EVP_KDF_*` and `EVP_KDF_CTX_*` bindings.
* Added `EVP_DigestSqueeze`.
* Added `OSSL_PARAM_construct_octet_string`.
* Added `OSSL_set_max_threads` and `OSSL_get_max_threads`.
### Changed
* `openssl-sys` is now a 2021 edition crate
* Explicitly specify the MSRV in `Cargo.toml`
* Raised the `bindgen` (optional) dependency from 0.65 to 0.69
## [v0.9.103] - 2024-07-20
### Added
* Added several functions and constants for datagram `BIO`s.
* Added `EVP_PKEY_set1_DSA`, `EVP_PKEY_set1_DH`, and `EVP_PKEY_set1_EC_KEY`.
* Added several functions related to QUIC support.
## [v0.9.102] - 2024-03-28
### Added
* Added support for LibreSSL 3.9.x.
## [v0.9.101] - 2024-02-21
### Fixed
* Fixed a bug where, when building with the `vendored` feature, this crate always needed to be rebuilt.
## [v0.9.100] - 2024-02-19
### Added
* Added `OSSL_PARAM`, `OSSL_PARAM_construct_uint` , `OSSL_PARAM_construct_end`.
* Added `EVP_PKEY_CTX_set_params` and `EVP_PKEY_CTX_get_params`.
* Added `X509_alias_get0`.
* Added `EVP_default_properties_enable_fips`.
## [v0.9.99] - 2024-01-19
### Added
* On macOS added Homebrew's `openssl@3.0` to the list of candidates to build against.
* `NID_brainpoolP256r1`, `NID_brainpoolP320r1`, `NID_brainpoolP384r1`, and `NID_brainpoolP512r1` are now available on LibreSSL.
### Changed
* `X509_PURPOSE` is now opaque on LibreSSL 3.9.0+.
## [v0.9.98] - 2023-12-22
### Added
* Added `RAND_priv_bytes`.
* Added `NID_brainpoolP320r1`.
### Changed
* `X509_PURPOSE_get0` now returns a `const` pointer on LibreSSL 3.9.0+.
* `X509V3_EXT_add_alias` is removed on LibreSSL 3.9.0+.
## [v0.9.97] - 2023-12-04
### Changed
* libatomic is no longer dynamically linked for 32 bit ARM targets.
### Added
* Added `SSL_read_ex`, `SSL_peek_ex`, and `SSL_write_ex`.
## [v0.9.96] - 2023-11-22
### Changed
* `EVP_chacha20` is now available on LibreSSL
### Added
* Added `EVP_des_ede3_ecb`, `EVP_des_ede3_cfb8`, `EVP_des_ede3_ofb`, `EVP_camellia_128_ofb`, `EVP_camellia_192_ofb`, `EVP_camellia_256_ofb`, `EVP_cast5_ofb`, `EVP_idea_ofb`
* Added `X509_STORE_get1_all_certs`
* Added `SSL_CTRL_GET_PEER_TMP_KEY`, `SSL_CTRL_GET_TMP_KEY`, `SSL_get_peer_tmp_key`, `SSL_get_tmp_key`
## [v0.9.95] - 2023-11-03
### Changed
* Fixed the availability of `EVP_PKEY_RSA_PSS` on OpenSSL
### Added
* Added support for LibreSSL 3.8.x.
* Added `NID_chacha20_poly1305`
## [v0.9.94] - 2023-11-01
### Changed
* `X509_ALGOR` is now opaque on new LibreSSL releases
### Added
* Added support for building with `OPENSSL_NO_SCRYPT`
* Added `EVP_PKEY_RSA_PSS` and `EVP_PKEY_DHX`
* Functions and constants for using HKDF `EVP_PKEY` are now available on LibreSSL.
* Added `SSL_CTX_set_security_level`, `SSL_set_security_level`, `SSL_CTX_get_security_level`, `SSL_get_security_level`
* Added `X509_check_host`, `X509_check_email`, `X509_check_ip`, `X509_check_ip_asc`
## [v0.9.93] - 2023-09-04
### Changed
* The `vendored` Cargo feature now builds OpenSSL 3.1, as 1.1.1 is reaching its EOL.
### Added
* Added support for LibreSSL 3.8.1.
## [v0.9.92] - 2023-08-27
### Added
* Added `EVP_CIPHER_CTX_copy`
* Expose `EVP_chacha20_poly1305` on LibreSSL
* Added `X509_VERIFY_PARAM_set1_email`
## [v0.9.91] - 2023-08-06
### Added
* Expose `poly1305_state`, `CRYPTO_poly1305_init`, `CRYPTO_poly1305_update`, and `CRYPTO_poly1305_finish` on BoringSSL and LibreSSL.
* Fix detection of libraries on OpenBSD.
* Added `EC_POINT_point2hex` and `EC_POINT_hex2point`.
* Added `EVP_PKEY_verify_recover_init`, `EVP_PKEY_verify_recover`, and `EVP_PKEY_CTX_set_signature_md`.
* Added `EVP_CIPHER_CTX_FLAG_WRAP_ALLOW` and `EVP_CTX_set_flags`.
* Added `BN_mod_sqrt`.
## [v0.9.90] - 2023-06-20
### Fixed
* Fixed compilation with BoringSSL when building with the bindgen CLI.
## [v0.9.89] - 2023-06-20
### Fixed
* Fixed compilation with recent versions of BoringSSL.
### Added
* Added support for detecting OpenSSL compiled with `OPENSSL_NO_OCB`.
* Added `EVP_PKEY_SM2` and `NID_sm2`.
* Added `EVP_PKEY_assign_RSA`, `EVP_PKEY_assign_DSA`, `EVP_PKEY_assign_DH`, and `EVP_PKEY_assign_EC_KEY`.
* Added `EC_GROUP_get_asn1_flag`.
* Expose `EC_POINT_get_affine_coordinates` on BoringSSL and LibreSSL.
* Added `EVP_PKEY_derive_set_peer_ex`.
## [v0.9.88] - 2023-05-30
### Added
* Added support for the LibreSSL 3.8.0.
* Added support for detecting `OPENSSL_NO_RC4`.
* Added `OBJ_dup`.
* Added `ASN1_TYPE_new`, `ASN1_TYPE_set`, `d2i_ASN1_TYPE`, and `i2d_ASN1_TYPE`.
* Added `SSL_bytes_to_cipher_list`, `SSL_CTX_get_num_tickets`, and `SSL_get_num_tickets`.
* Added `GENERAL_NAME_set0_othername`.
* Added `X509_get_pathlen`.
## [v0.9.87] - 2023-04-24
### Added
* Added `DH_CHECK`.
* Added `CMAC_CTX_new`, `CMAC_CTX_free`, `CMAC_Init`, `CMAC_Update`, `CMAC_Final`, and `CMAC_CTX_copy`.
* Added `EVP_default_properties_is_fips_enabled`.
* Added `X509_get0_subject_key_id`, `X509_get0_authority_key_id`, `X509_get0_authority_issuer`, and `X509_get0_authority_serial`.
* Added `NID_poly1305`.
## [v0.9.86] - 2023-04-20
### Fixed
* Fixed BoringSSL support with the latest bindgen release.
### Added
* Added bindings for PKCS#7 functions and more X.509 functions.
## [v0.9.85] - 2023-04-09
### Added
* Added support for LibreSSL 3.7.x.
## [v0.9.84] - 2023-04-01
### Added
* Added `ASN1_INTEGER_dup` and `ASN1_INTEGER_cmp`.
* Added `stack_st_X509_NAME_ENTRY`.
* Added `DIST_POINT_NAME`, `DIST_POINT`, `stack_st_DIST_POINT`, `DIST_POINT_free`, and `DIST_POINT_NAME_free`.
## [v0.9.83] - 2023-03-23
### Fixed
* Fixed version checks for LibreSSL.
### Added
* Added `i2d_X509_EXTENSION`.
* Added `GENERAL_NAME_new`.
## [v0.9.82] - 2023-03-19
### Added
* Added support for LibreSSL 3.7.1.
* Added support for X25519 and Ed25519 on LibreSSL and BoringSSL.
## [v0.9.81] - 2023-03-14
### Fixed
Fixed builds against OpenSSL built with `no-cast`.
### Added
* Added experimental bindgen support for BoringSSL.
* Added `X509_VERIFY_PARAM_set_auth_level`, `X509_VERIFY_PARAM_get_auth_level`, and `X509_VERIFY_PARAM_set_purpose`.
* Added `X509_PURPOSE_*` consts.
* Added `X509_NAME_add_entry`.
* Added `X509_load_crl_file`.
* Added `SSL_set_cipher_list`, `SSL_set_ssl_method`, `SSL_use_PrivateKey_file`, `SSL_use_PrivateKey`, `SSL_use_certificate`, `SSL_use_certificate_chain_file`, `SSL_set_client_CA_list`, `SSL_add_client_CA`, and `SSL_set0_verify_cert_store`.
* Added `X509_PURPOSE`, `X509_STORE_set_purpose`, and `X509_STORE_set_trust`.
* Added `SSL_CTX_set_num_tickets`, `SSL_set_num_tickets`, `SSL_CTX_get_num_tickets`, and `SSL_get_num_tickets`.
* Added `CMS_verify`.
### Removed
* Removed an unnecessary link to libatomic for 32-bit android targets.
## [v0.9.80] - 2022-12-20
### Fixed
* Added `NO_DEPRECATED_3_0` cfg checks for more APIs.
### Added
* Added support for LibreSSL 3.7.0.
* Added `SSL_CTRL_CHAIN_CERT` and `SSL_add0_chain_cert`.
* Added `EVP_PKEY_get_security_bits` and `EVP_PKEY_security_bits`.
* Added `OSSL_PROVIDER_set_default_search_path`.
## [v0.9.79] - 2022-12-06
### Added
* Added `EVP_CIPHER_CTX_num`.
* Added `X509_LOOKUP_file` and `X509_load_cert_file`.
## [v0.9.78] - 2022-11-23
### Added
* Added support for LibreSSL 3.6.x.
* Added `NID_brainpoolP256r1`, `NID_brainpoolP384r1`, and `NID_brainpool512r1`.
* Added `EVP_camellia_128_cfb128`, `EVP_camellia_128_ecb`, `EVP_camellia_192_cfb128`, `EVP_camellia_192_ecb`,
`EVP_camellia_256_cfb128`, and `EVP_camellia_256_ecb`.
* Added `EVP_cast5_cfb64` and `EVP_cast5_ecb`.
* Added `EVP_idea_cfb64` and `EVP_idea_ecb`.
* Added `DSA_SIG`, `d2i_DSA_SIG`, `i2d_DSA_SIG`, `DSA_SIG_new`, `DSA_SIG_free`, `DSA_SIG_get0`, and `DSA_SIG_set0`.
* Added `X509_STORE_set1_param`, `X509_VERIFY_PARAM_new`, `X509_VERIFY_PARAM_set_time`, and
`X509_VERIFY_PARAM_set_depth`.
## [v0.9.77] - 2022-10-22
### Added
* Added support for LibreSSL 3.6.0
* Added `assume_init`.
## [v0.9.76] - 2022-09-26
### Added
* Added `SSL_get_psk_identity_hint` and `SSL_get_psk_identity`.
* Added SHA-3 NID constants.
* Added `SSL_OP_PRIORITIZE_CHACHA`.
* Added `X509_REQ_print`.
* Added `EVP_MD_CTX_size` and `EVP_MD_CTX_get_size`
* Added `EVP_MD_CTX_reset`.
* Added experimental, unstable support for BoringSSL.
### Fixed
* Fixed the deprecation note on `SSL_CTX_set_alpn_select_cb`.
## [v0.9.75] - 2022-07-09
### Added
* Added SM4 bindings.
* Added `EC_GROUP_set_generator` and `EC_POINT_set_affine_coordinates_GFp`.
## [v0.9.74] - 2022-06-01
### Added
* Added `EVP_MD_block_size`.
* Added `X509V3_EXT_add_alias`.
* Added `X509_V_ERR_INVALID_CA` back when building against OpenSSL 3.0.
## [v0.9.73] - 2022-05-02
### Added
* Added support for installations that place libraries in `$OPENSSL_DIR/lib64` in addition to `$OPENSSL_DIR/lib`.
* Added `X509_issuer_name_hash`.
* Added `ASN1_string_set`.
* Added `X509_CRL_dup`, `X509_REQ_dup`, `X509_NAME_dup`, and `X509_dup`.
* Added `X509_print`.
* Added support for LibreSSL 3.5.x.
## [v0.9.72] - 2021-12-11
### Changed
* Temporarily downgraded the vendored OpenSSL back to 1.1.1 due to significant performance regressions. We will move
back to 3.0.0 when a future release resolves those issues.
### Added
* Added `PKCS12_set_mac`.
* Added `EVP_PKEY_sign_init`, `EVP_PKEY_sign`, `EVP_PKEY_verify_init`, and `EVP_PKEY_verify`.
* Added support for LibreSSL 3.4.x.
## [v0.9.71]
### Fixed
* Fixed linkage to static OpenSSL 3.0.0 libraries on some 32 bit Android targets.
### Added
* Added support for LibreSSL 3.4.1.
* Added `SSL_get_extms_support` and `SSL_CTRL_GET_EXTMS_SUPPORT`.
* Added `OBJ_create`.
* Added `EVP_CIPHER_CTX_get0_cipher`, `EVP_CIPHER_CTX_get_block_size`, `EVP_CIPHER_CTX_get_key_length`,
`EVP_CIPHER_CTX_get_iv_length`, and `EVP_CIPHER_CTX_get_tag_length`.
* Added `EVP_CIPHER_free`.
* Added `EVP_CIPHER_CTX_rand_key`.
* Added `OSSL_LIB_CTX_new` and `OSSL_LIB_CTX_free`.
* Added `EVP_CIPHER_fetch`.
* Added `EVP_MD_fetch` and `EVP_MD_free`.
* Added `OPENSSL_malloc` and `OPENSSL_free`.
* Added `EVP_DigestSignUpdate` and `EVP_DigestVerifyUpdate`.
## [v0.9.70] - 2021-10-31
### Fixed
* Fixed linkage to static 3.0.0 OpenSSL libraries on some 32 bit architectures.
## [v0.9.69] - 2021-10-31
### Changed
* Upgraded the vendored OpenSSL to 3.0.0.
### Added
* Added support for automatic detection of Homebrew `openssl@3` installs.
* Added `EVP_PKEY_Q_keygen` and `EVP_EC_gen`.
## [v0.9.68] - 2021-10-27
### Added
* Added `BN_bn2binpad`.
* Added `i2d_X509_NAME` and `d2i_X509_NAME`.
* Added `BN_FLG_MALLOCED`, `BN_FLG_STATIC_DATA`, `BN_FLG_CONSTTIME`, and `BN_FLG_SECURE`.
* Added `BN_CTX_secure_new`, `BN_secure_new`, `BN_set_flags`, and `BN_get_flags`.
## [v0.9.67] - 2021-09-21
### Added
* Added support for LibreSSL 3.4.0
## [v0.9.66] - 2021-08-17
### Added
* Added `EVP_seed_cbc`, `EVP_seed_cfb128`, `EVP_seed_ecb`, and `EVP_seed_ofb`.
* Added `OBJ_length` and `OBJ_get0_data`.
* Added `i2d_PKCS8PrivateKey_bio`.
## [v0.9.65] - 2021-06-21
### Fixed
* Restored the accidentally deleted `PEM_read_bio_X509_CRL` function.
## [v0.9.64] - 2021-06-18
### Added
* Added support for OpenSSL 3.x.x.
* Added `SSL_peek`.
* Added `ERR_LIB_ASN1` and `ASN1_R_HEADER_TOO_LONG`.
* Added `d2i_X509_bio`.
* Added `OBJ_nid2obj`.
* Added `RAND_add`.
* Added `SSL_CTX_set_post_handshake_auth`.
* Added `COMP_get_type`.
* Added `X509_get_default_cert_file_env`, `X509_get_default_cert_file`, `X509_get_default_cert_dir_env`, and
`X509_get_default_cirt_dir`.
## [v0.9.63] - 2021-05-06
### Added
* Added support for LibreSSL 3.3.x.
## [v0.9.62] - 2021-04-28
### Added
* Added support for LibreSSL 3.3.2.
* Added `DH_set0_key`.
* Added `EC_POINT_get_affine_coordinates`.
## [v0.9.61] - 2021-03-13
### Added
* Added support for automatic detection of OpenSSL installations via pkgsrc and MacPorts on macOS.
* Added various `V_ASN1_*` constants.
* Added `DH_generate_parameters_ex`.
* Added `EC_POINT_is_at_infinity` and `EC_POINT_is_on_curve`.
* Added `EVP_CIPHER_nid`.
* Added `EVP_sm3`.
* Added `NID_*` constants related to SM3.
* Added `PKCS7_get0_signers`.
* Added `EVP_PKEY_CTX_set0_rsa_oaep_label`.
* Added `ACCESS_DESCRIPTION` and `ACCESS_DESCRIPTION_free`.
## [v0.9.60] - 2020-12-24
### Added
* Added support for the default Homebrew install directory on ARM.
* Added `EVP_PKEY_CTX_set_rsa_oaep_md` and `EVP_PKEY_CTRL_RSA_OAEP_MD`.
## [v0.9.59] - 2020-12-09
### Added
* Added support for LibreSSL 3.2.x, 3.3.0, and 3.3.1.
* Added `DH_generate_parameters`, `DH_generate_key`, `DH_compute_key`, and `DH_size`.
* Added `NID_X25519`, `NID_X448`, `EVP_PKEY_x25519` and `EVP_PKEY_x448`.
* Added `OBJ_txt2obj`.
* Added `d2i_PKCS7` and `i2d_PKCS7`.
* Added `SRTP_AEAD_AES_128_GCM` and `SRTP_AEAD_AES_256_GCM`.
## [v0.9.58] - 2020-06-05
### Added
* Added `SSL_set_mtu`.
* Added support for LibreSSL 3.2.0.
* Added `PEM_read_bio_EC_PUBKEY`, `PEM_write_bio_EC_PUBKEY`, `d2i_EC_PUBKEY`, and `i2d_EC_PUBKEY`.
* Added `EVP_PKEY_encrypt_init`, `EVP_PKEY_encrypt`, `EVP_PKEY_decrypt_init`, `EVP_PKEY_decrypt`,
`EVP_PKEY_get_raw_public_key`, `EVP_PKEY_new_raw_public_key`, `EVP_PKEY_get_raw_private_key`,
and `EVP_PKEY_new_raw_private_key`.
* Added `OBJ_sn2nid`.
## [v0.9.57] - 2020-05-24
### Added
* Added support for LibreSSL 3.1.x.
## [v0.9.56] - 2020-05-07
### Fixed
* Fixed vendored builds on windows-gnu targets.
### Added
* Added support for LibreSSL 3.0.0.
## [v0.9.55] - 2020-04-07
### Fixed
* Fixed windows-msvc library names when using OpenSSL from vcpkg.
### Added
* If the `OPENSSL_NO_VENDOR` environment variable is set, vendoring will not be used even if enabled.
* Added `SSL_CTX_get_verify_mode` and `SSL_get_verify_mode`.
* Added `SSL_is_init_finished`.
* Added `SSL_CTX_set_cert_store`.
* Added `TLS_server_method` and `TLS_client_method`.
* Added `X509_STORE_get0_objects`.
* Added `X509_OBJECT_free`, `X509_OBJECT_get_type`, and `X509_OBJECT_get0_X509`.
## [v0.9.54] - 2020-01-29
### Added
* Added `BIO_CTRL_DGRAM_QUERY_MTU`.
* Added `EVP_EncryptInit_ex`, `EVP_EncryptFinal_ex`, `EVP_DecryptInit_ex`, and `EVP_DecryptFinal_ex`.
* Added `EVP_md_null`.
* Added `EVP_PKCS82PKEY`.
* Added `PKCS8_PRIV_KEY_INFO`, `d2i_PKCS8_PRIV_KEY_INFO`, and `PKCS8_PRIV_KEY_INFO_free`.
* Added `SSL_OP_NO_RENEGOTIATION`.
## [v0.9.53] - 2019-11-22
### Added
* Added `ASN1_TIME_diff`.
* Added `EC_GROUP_order_bits`.
* Added `EVP_EncodeBlock` and `EVP_DecodeBlock`.
* Added `SSL_CTRL_SET_GROUPS_LIST`, `SSL_CTRL_SET_SIGALGS_LIST`, `SSL_CTX_set1_groups_list`, and
`SSL_CTX_set1_sigalgs_list`.
* Added `Clone` implementations to `SHA_CTX`, `SHA256_CTX`, and `SHA512_CTX`.
## [v0.9.52] - 2019-10-19
### Added
* Added support for LibreSSL 3.0.x.
## [v0.9.51] - 2019-10-02
### Added
* Added support for LibreSSL 3.0.1.
## [v0.9.50] - 2019-10-02
### Added
* Added `CRYPTO_LOCK_EVP_PKEY`.
* Added `EVP_PKEY_ED25519` and `EVP_PKEY_ED448`.
* Added `EVP_DigestSign` and `EVP_DigestVerify`.
* Added `EVP_PKEY_up_ref`.
* Added `NID_ED25519` and `NID_ED448`.
## [v0.9.49] - 2019-08-15
### Added
* Added support for LibreSSL 3.0.0.
## [v0.9.48] - 2019-07-19
### Added
* Added `AES_wrap_key` and `AES_unwrap_key`.
* Added `EC_GROUP_get_cofactor`, `EC_GROUP_get0_generator`, and `EC_POINT_dup`.
* Added `EVP_aes_128_ofb`, `EVP_aes_192_ecb`, `EVP_aes_192_cbc`, `EVP_aes_192_cfb1`, `EVP_aes_192_cfb8`,
`EVP_aes_192_cfb_128`, `EVP_aes_192_ctr`, `EVP_aes_192_ccm`, `EVP_aes_192_gcm`, `EVP_aes_192_ofb`, and
`EVP_aes_256_ofb`.
* Added `PEM_read_bio_CMS` and `PEM_write_bio_CMS`.
## [v0.9.47] - 2019-05-18
### Added
* Added `SSL_CTX_add_client_CA`.
## [v0.9.46] - 2019-05-08
### Added
* Added support for the LibreSSL 2.9.x series.
## [v0.9.45] - 2019-05-03
### Fixed
* Reverted a change to windows-gnu library names that caused regressions.
## [v0.9.44] - 2019-04-30
### Added
* The `DEP_OPENSSL_VENDORED` environment variable tells downstream build scripts if the vendored feature was enabled.
* Added `EVP_SealInit`, `EVP_SealFinal`, `EVP_EncryptUpdate`, `EVP_OpenInit`, `EVP_OpenFinal`, and `EVP_DecryptUpdate`.
* Added `EVP_PKEY_size`.
### Fixed
* Fixed library names when targeting windows-gnu and pkg-config fails.
## [v0.9.43] - 2019-03-20
### Added
* Added `d2i_CMS_ContentInfo` and `CMS_encrypt`.
* Added `X509_verify` and `X509_REQ_verify`.
* Added `EVP_MD_type` and `EVP_GROUP_get_curve_name`.
[Unreleased]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.111..master
[v0.9.111]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.110...openssl-sys-v0.9.111
[v0.9.110]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.109...openssl-sys-v0.9.110
[v0.9.109]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.108...openssl-sys-v0.9.109
[v0.9.108]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.107...openssl-sys-v0.9.108
[v0.9.107]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.106...openssl-sys-v0.9.107
[v0.9.106]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.105...openssl-sys-v0.9.106
[v0.9.105]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.104...openssl-sys-v0.9.105
[v0.9.104]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.103...openssl-sys-v0.9.104
[v0.9.103]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.102...openssl-sys-v0.9.103
[v0.9.102]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.101...openssl-sys-v0.9.102
[v0.9.101]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.100...openssl-sys-v0.9.101
[v0.9.100]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.99...openssl-sys-v0.9.100
[v0.9.99]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.98...openssl-sys-v0.9.99
[v0.9.98]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.97...openssl-sys-v0.9.98
[v0.9.97]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.96...openssl-sys-v0.9.97
[v0.9.96]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.95...openssl-sys-v0.9.96
[v0.9.95]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.94...openssl-sys-v0.9.95
[v0.9.94]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.93...openssl-sys-v0.9.94
[v0.9.93]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.92...openssl-sys-v0.9.93
[v0.9.92]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.91...openssl-sys-v0.9.92
[v0.9.91]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.90...openssl-sys-v0.9.91
[v0.9.90]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.89...openssl-sys-v0.9.90
[v0.9.89]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.88...openssl-sys-v0.9.89
[v0.9.88]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.87...openssl-sys-v0.9.88
[v0.9.87]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.86...openssl-sys-v0.9.87
[v0.9.86]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.85...openssl-sys-v0.9.86
[v0.9.85]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.84...openssl-sys-v0.9.85
[v0.9.84]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.83...openssl-sys-v0.9.84
[v0.9.83]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.82...openssl-sys-v0.9.83
[v0.9.82]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.81...openssl-sys-v0.9.82
[v0.9.81]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.80...openssl-sys-v0.9.81
[v0.9.80]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.79...openssl-sys-v0.9.80
[v0.9.79]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.78...openssl-sys-v0.9.79
[v0.9.78]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.77...openssl-sys-v0.9.78
[v0.9.77]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.76...openssl-sys-v0.9.77
[v0.9.76]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.75...openssl-sys-v0.9.76
[v0.9.75]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.74...openssl-sys-v0.9.75
[v0.9.74]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.73...openssl-sys-v0.9.74
[v0.9.73]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.72...openssl-sys-v0.9.73
[v0.9.72]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.71...openssl-sys-v0.9.72
[v0.9.71]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.70...openssl-sys-v0.9.71
[v0.9.70]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.69...openssl-sys-v0.9.70
[v0.9.69]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.68...openssl-sys-v0.9.69
[v0.9.68]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.67...openssl-sys-v0.9.68
[v0.9.67]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.66...openssl-sys-v0.9.67
[v0.9.66]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.65...openssl-sys-v0.9.66
[v0.9.65]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.64...openssl-sys-v0.9.65
[v0.9.64]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.63...openssl-sys-v0.9.64
[v0.9.63]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.62...openssl-sys-v0.9.63
[v0.9.62]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.61...openssl-sys-v0.9.62
[v0.9.61]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.60...openssl-sys-v0.9.61
[v0.9.60]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.59...openssl-sys-v0.9.60
[v0.9.59]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.58...openssl-sys-v0.9.59
[v0.9.58]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.57...openssl-sys-v0.9.58
[v0.9.57]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.56...openssl-sys-v0.9.57
[v0.9.56]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.55...openssl-sys-v0.9.56
[v0.9.55]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.54...openssl-sys-v0.9.55
[v0.9.54]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.53...openssl-sys-v0.9.54
[v0.9.53]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.52...openssl-sys-v0.9.53
[v0.9.52]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.51...openssl-sys-v0.9.52
[v0.9.51]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.50...openssl-sys-v0.9.51
[v0.9.50]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.49...openssl-sys-v0.9.50
[v0.9.49]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.48...openssl-sys-v0.9.49
[v0.9.48]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.47...openssl-sys-v0.9.48
[v0.9.47]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.46...openssl-sys-v0.9.47
[v0.9.46]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.45...openssl-sys-v0.9.46
[v0.9.45]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.44...openssl-sys-v0.9.45
[v0.9.44]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.43...openssl-sys-v0.9.44
[v0.9.43]: https://github.com/rust-openssl/rust-openssl/compare/openssl-sys-v0.9.42...openssl-sys-v0.9.43

View File

@@ -0,0 +1,593 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "annotate-snippets"
version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4"
dependencies = [
"anstyle",
"unicode-width",
]
[[package]]
name = "anstyle"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
[[package]]
name = "aws-lc-fips-sys"
version = "0.13.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e78aabce84ab79501f4777e89cdcaec2a6ba9b051e6e6f26496598a84215c26"
dependencies = [
"bindgen 0.72.1",
"cc",
"cmake",
"dunce",
"fs_extra",
"libloading",
"regex",
]
[[package]]
name = "aws-lc-sys"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77926887776171ced7d662120a75998e444d3750c951abfe07f90da130514b1f"
dependencies = [
"bindgen 0.69.5",
"cc",
"cmake",
"dunce",
"fs_extra",
]
[[package]]
name = "bindgen"
version = "0.69.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
dependencies = [
"bitflags",
"cexpr",
"clang-sys",
"itertools 0.12.1",
"lazy_static",
"lazycell",
"log",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"rustc-hash 1.1.0",
"shlex",
"syn",
"which",
]
[[package]]
name = "bindgen"
version = "0.72.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
dependencies = [
"annotate-snippets",
"bitflags",
"cexpr",
"clang-sys",
"itertools 0.13.0",
"log",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"rustc-hash 2.1.1",
"shlex",
"syn",
]
[[package]]
name = "bitflags"
version = "2.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
[[package]]
name = "bssl-sys"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "312d12393c060384f2e6ed14c7b4be37b3dd90249857485613c1a91b9a1abb5c"
[[package]]
name = "cc"
version = "1.2.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7"
dependencies = [
"find-msvc-tools",
"jobserver",
"libc",
"shlex",
]
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
[[package]]
name = "clang-sys"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "cmake"
version = "0.1.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0"
dependencies = [
"cc",
]
[[package]]
name = "dunce"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "errno"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.61.2",
]
[[package]]
name = "find-msvc-tools"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
[[package]]
name = "fs_extra"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]]
name = "getrandom"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi",
]
[[package]]
name = "glob"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
[[package]]
name = "home"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "itertools"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
dependencies = [
"either",
]
[[package]]
name = "jobserver"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
dependencies = [
"getrandom",
"libc",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.177"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
[[package]]
name = "libloading"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
dependencies = [
"cfg-if",
"windows-targets",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "log"
version = "0.4.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
[[package]]
name = "memchr"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "openssl-src"
version = "300.5.3+3.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc6bad8cd0233b63971e232cc9c5e83039375b8586d2312f31fda85db8f888c2"
dependencies = [
"cc",
]
[[package]]
name = "openssl-sys"
version = "0.9.111"
dependencies = [
"aws-lc-fips-sys",
"aws-lc-sys",
"bindgen 0.72.1",
"bssl-sys",
"cc",
"libc",
"openssl-src",
"pkg-config",
"vcpkg",
]
[[package]]
name = "pkg-config"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "prettyplease"
version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "regex"
version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a52d8d02cacdb176ef4678de6c052efb4b3da14b78e4db683a4252762be5433"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "722166aa0d7438abbaa4d5cc2c649dac844e8c56d82fb3d33e9c34b5cd268fc6"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3160422bbd54dd5ecfdca71e5fd59b7b8fe2b1697ab2baf64f6d05dcc66d298"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc-hash"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
[[package]]
name = "rustix"
version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
[[package]]
name = "unicode-width"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "wasi"
version = "0.14.7+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c"
dependencies = [
"wasip2",
]
[[package]]
name = "wasip2"
version = "1.0.1+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "which"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
dependencies = [
"either",
"home",
"once_cell",
"rustix",
]
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "wit-bindgen"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"

View File

@@ -0,0 +1,87 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2021"
rust-version = "1.70.0"
name = "openssl-sys"
version = "0.9.111"
authors = [
"Alex Crichton <alex@alexcrichton.com>",
"Steven Fackler <sfackler@gmail.com>",
]
build = "build/main.rs"
links = "openssl"
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "FFI bindings to OpenSSL"
readme = "README.md"
categories = [
"cryptography",
"external-ffi-bindings",
]
license = "MIT"
repository = "https://github.com/rust-openssl/rust-openssl"
[package.metadata.pkg-config]
openssl = "1.0.1"
[features]
aws-lc = ["dep:aws-lc-sys"]
aws-lc-fips = ["dep:aws-lc-fips-sys"]
unstable_boringssl = ["bssl-sys"]
vendored = ["openssl-src"]
[lib]
name = "openssl_sys"
path = "src/lib.rs"
[dependencies.aws-lc-fips-sys]
version = "0.13"
features = [
"ssl",
"bindgen",
]
optional = true
[dependencies.aws-lc-sys]
version = "0.27"
features = ["ssl"]
optional = true
[dependencies.bssl-sys]
version = "0.1.0"
optional = true
[target.'cfg(not(target_os = "unknown"))'.dependencies.libc]
version = "0.2"
[build-dependencies.bindgen]
version = "0.72.0"
features = ["experimental"]
optional = true
[build-dependencies.cc]
version = "1.0.61"
[build-dependencies.openssl-src]
version = "300.2.0"
features = ["legacy"]
optional = true
[build-dependencies.pkg-config]
version = "0.3.9"
[build-dependencies.vcpkg]
version = "0.2.8"

View File

@@ -0,0 +1,39 @@
[package]
name = "openssl-sys"
version = "0.9.111"
authors = [
"Alex Crichton <alex@alexcrichton.com>",
"Steven Fackler <sfackler@gmail.com>",
]
license = "MIT"
description = "FFI bindings to OpenSSL"
repository = "https://github.com/rust-openssl/rust-openssl"
readme = "README.md"
categories = ["cryptography", "external-ffi-bindings"]
links = "openssl"
build = "build/main.rs"
edition = "2021"
rust-version = "1.70.0"
[features]
vendored = ['openssl-src']
unstable_boringssl = ['bssl-sys']
aws-lc = ['dep:aws-lc-sys']
aws-lc-fips = ['dep:aws-lc-fips-sys']
[dependencies]
libc = "0.2"
bssl-sys = { version = "0.1.0", optional = true }
aws-lc-sys = { version = "0.27", features = ["ssl"], optional = true }
aws-lc-fips-sys = { version = "0.13", features = ["ssl", "bindgen"], optional = true }
[build-dependencies]
bindgen = { version = "0.72.0", optional = true, features = ["experimental"] }
cc = "1.0.61"
openssl-src = { version = "300.2.0", optional = true, features = ["legacy"] }
pkg-config = "0.3.9"
vcpkg = "0.2.8"
# We don't actually use metadeps for annoying reasons but this is still here for tooling
[package.metadata.pkg-config]
openssl = "1.0.1"

View File

@@ -0,0 +1,25 @@
Copyright (c) 2014 Alex Crichton
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR 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.

View File

@@ -0,0 +1,22 @@
# rust-openssl
[![crates.io](https://img.shields.io/crates/v/openssl.svg)](https://crates.io/crates/openssl)
OpenSSL bindings for the Rust programming language.
[Documentation](https://docs.rs/openssl).
## Release Support
The current supported release of `openssl` is 0.10 and `openssl-sys` is 0.9.
New major versions will be published at most once per year. After a new
release, the previous major version will be partially supported with bug
fixes for 3 months, after which support will be dropped entirely.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally
submitted for inclusion in the work by you, as defined in the Apache-2.0
license, shall be dual licensed under the terms of both the Apache License,
Version 2.0 and the MIT license without any additional terms or conditions.

View File

@@ -0,0 +1,103 @@
#[allow(clippy::unusual_byte_groupings)]
pub fn get(openssl_version: Option<u64>, libressl_version: Option<u64>) -> Vec<&'static str> {
let mut cfgs = vec![];
if let Some(libressl_version) = libressl_version {
cfgs.push("libressl");
cfgs.push("libressl251");
cfgs.push("libressl252");
cfgs.push("libressl261");
cfgs.push("libressl270");
cfgs.push("libressl271");
cfgs.push("libressl273");
cfgs.push("libressl280");
cfgs.push("libressl281");
cfgs.push("libressl291");
cfgs.push("libressl310");
cfgs.push("libressl321");
cfgs.push("libressl332");
cfgs.push("libressl340");
cfgs.push("libressl350");
if libressl_version >= 0x3_06_00_00_0 {
cfgs.push("libressl360");
}
if libressl_version >= 0x3_07_00_00_0 {
cfgs.push("libressl370");
}
if libressl_version >= 0x3_08_00_00_0 {
cfgs.push("libressl380");
}
if libressl_version >= 0x3_08_01_00_0 {
cfgs.push("libressl381");
}
if libressl_version >= 0x3_08_02_00_0 {
cfgs.push("libressl382");
}
if libressl_version >= 0x3_09_00_00_0 {
cfgs.push("libressl390");
}
if libressl_version >= 0x4_00_00_00_0 {
cfgs.push("libressl400");
}
if libressl_version >= 0x4_01_00_00_0 {
cfgs.push("libressl410");
}
if libressl_version >= 0x4_02_00_00_0 {
cfgs.push("libressl420");
}
} else {
let openssl_version = openssl_version.unwrap();
cfgs.push("ossl101");
cfgs.push("ossl102");
if openssl_version >= 0x1_00_02_06_0 {
cfgs.push("ossl102f");
}
if openssl_version >= 0x1_00_02_08_0 {
cfgs.push("ossl102h");
}
if openssl_version >= 0x1_01_00_00_0 {
cfgs.push("ossl110");
}
if openssl_version >= 0x1_01_00_06_0 {
cfgs.push("ossl110f");
}
if openssl_version >= 0x1_01_00_07_0 {
cfgs.push("ossl110g");
}
if openssl_version >= 0x1_01_00_08_0 {
cfgs.push("ossl110h");
}
if openssl_version >= 0x1_01_01_00_0 {
cfgs.push("ossl111");
}
if openssl_version >= 0x1_01_01_02_0 {
cfgs.push("ossl111b");
}
if openssl_version >= 0x1_01_01_03_0 {
cfgs.push("ossl111c");
}
if openssl_version >= 0x1_01_01_04_0 {
cfgs.push("ossl111d");
}
if openssl_version >= 0x3_00_00_00_0 {
cfgs.push("ossl300");
}
if openssl_version >= 0x3_02_00_00_0 {
cfgs.push("ossl320");
}
if openssl_version >= 0x3_03_00_00_0 {
cfgs.push("ossl330");
}
if openssl_version >= 0x3_04_00_00_0 {
cfgs.push("ossl340");
}
if openssl_version >= 0x3_05_00_00_0 {
cfgs.push("ossl350");
}
}
cfgs
}

View File

@@ -0,0 +1,158 @@
#include <openssl/opensslv.h>
#include <openssl/opensslconf.h>
#define VERSION2(n, v) RUST_VERSION_##n##_##v
#define VERSION(n, v) VERSION2(n, v)
#define NEW_VERSION2(a, b, c) RUST_VERSION_NEW_OPENSSL_##a##_##b##_##c
#define NEW_VERSION(a, b, c) NEW_VERSION2(a, b, c)
#ifdef LIBRESSL_VERSION_NUMBER
VERSION(LIBRESSL, LIBRESSL_VERSION_NUMBER)
#elif defined OPENSSL_VERSION_MAJOR
NEW_VERSION(OPENSSL_VERSION_MAJOR, OPENSSL_VERSION_MINOR, OPENSSL_VERSION_PATCH)
#else
VERSION(OPENSSL, OPENSSL_VERSION_NUMBER)
#endif
#ifdef OPENSSL_IS_BORINGSSL
RUST_OPENSSL_IS_BORINGSSL
#endif
#ifdef OPENSSL_IS_AWSLC
RUST_OPENSSL_IS_AWSLC
#endif
#ifdef OPENSSL_NO_BF
RUST_CONF_OPENSSL_NO_BF
#endif
#ifdef OPENSSL_NO_BUF_FREELISTS
RUST_CONF_OPENSSL_NO_BUF_FREELISTS
#endif
#ifdef OPENSSL_NO_CHACHA
RUST_CONF_OPENSSL_NO_CHACHA
#endif
#ifdef OPENSSL_NO_IDEA
RUST_CONF_OPENSSL_NO_IDEA
#endif
#ifdef OPENSSL_NO_CAMELLIA
RUST_CONF_OPENSSL_NO_CAMELLIA
#endif
#ifdef OPENSSL_NO_CAST
RUST_CONF_OPENSSL_NO_CAST
#endif
#ifdef OPENSSL_NO_CMS
RUST_CONF_OPENSSL_NO_CMS
#endif
#ifdef OPENSSL_NO_COMP
RUST_CONF_OPENSSL_NO_COMP
#endif
#ifdef OPENSSL_NO_EC
RUST_CONF_OPENSSL_NO_EC
#endif
#ifdef OPENSSL_NO_EC2M
RUST_CONF_OPENSSL_NO_EC2M
#endif
#ifdef OPENSSL_NO_ENGINE
RUST_CONF_OPENSSL_NO_ENGINE
#endif
#ifdef OPENSSL_NO_KRB5
RUST_CONF_OPENSSL_NO_KRB5
#endif
#ifdef OPENSSL_NO_NEXTPROTONEG
RUST_CONF_OPENSSL_NO_NEXTPROTONEG
#endif
#ifdef OPENSSL_NO_OCSP
RUST_CONF_OPENSSL_NO_OCSP
#endif
#ifdef OPENSSL_NO_OCB
RUST_CONF_OPENSSL_NO_OCB
#endif
#ifdef OPENSSL_NO_PSK
RUST_CONF_OPENSSL_NO_PSK
#endif
#ifdef OPENSSL_NO_RC4
RUST_CONF_OPENSSL_NO_RC4
#endif
#ifdef OPENSSL_NO_RC2
RUST_CONF_OPENSSL_NO_RC2
#endif
#ifdef OPENSSL_NO_RFC3779
RUST_CONF_OPENSSL_NO_RFC3779
#endif
#ifdef OPENSSL_NO_RMD160
RUST_CONF_OPENSSL_NO_RMD160
#endif
#ifdef OPENSSL_NO_SHA
RUST_CONF_OPENSSL_NO_SHA
#endif
#ifdef OPENSSL_NO_SRP
RUST_CONF_OPENSSL_NO_SRP
#endif
#ifdef OPENSSL_NO_SRTP
RUST_CONF_OPENSSL_NO_SRTP
#endif
#ifdef OPENSSL_NO_SSL3_METHOD
RUST_CONF_OPENSSL_NO_SSL3_METHOD
#endif
#ifdef OPENSSL_NO_TLSEXT
RUST_CONF_OPENSSL_NO_TLSEXT
#endif
#ifdef OPENSSL_NO_SOCK
RUST_CONF_OPENSSL_NO_SOCK
#endif
#ifdef OPENSSL_NO_STDIO
RUST_CONF_OPENSSL_NO_STDIO
#endif
#ifdef OPENSSL_NO_SM3
RUST_CONF_OPENSSL_NO_SM3
#endif
#ifdef OPENSSL_NO_SM4
RUST_CONF_OPENSSL_NO_SM4
#endif
#ifdef OPENSSL_NO_DEPRECATED_3_0
RUST_CONF_OPENSSL_NO_DEPRECATED_3_0
#endif
#ifdef OPENSSL_NO_SEED
RUST_CONF_OPENSSL_NO_SEED
#endif
#ifdef OPENSSL_NO_SCRYPT
RUST_CONF_OPENSSL_NO_SCRYPT
#endif
#define SYMBOL_PREFIX2(X) RUST_BINDGEN_SYMBOL_PREFIX_##X##_
#define SYMBOL_PREFIX(X) SYMBOL_PREFIX2(X)
#if defined(OPENSSL_IS_AWSLC) && defined(BORINGSSL_PREFIX)
SYMBOL_PREFIX(BORINGSSL_PREFIX)
#endif

View File

@@ -0,0 +1,288 @@
use std::ffi::OsString;
use std::path::{Path, PathBuf};
use std::process::{self, Command};
use super::env;
pub fn get_openssl(target: &str) -> (Vec<PathBuf>, PathBuf) {
let lib_dir = env("OPENSSL_LIB_DIR").map(PathBuf::from);
let include_dir = env("OPENSSL_INCLUDE_DIR").map(PathBuf::from);
match (lib_dir, include_dir) {
(Some(lib_dir), Some(include_dir)) => (vec![lib_dir], include_dir),
(lib_dir, include_dir) => {
let openssl_dir = env("OPENSSL_DIR").unwrap_or_else(|| find_openssl_dir(target));
let openssl_dir = Path::new(&openssl_dir);
let lib_dir = lib_dir.map(|d| vec![d]).unwrap_or_else(|| {
let mut lib_dirs = vec![];
// OpenSSL 3.0 now puts it's libraries in lib64/ by default,
// check for both it and lib/.
if openssl_dir.join("lib64").exists() {
lib_dirs.push(openssl_dir.join("lib64"));
}
if openssl_dir.join("lib").exists() {
lib_dirs.push(openssl_dir.join("lib"));
}
lib_dirs
});
let include_dir = include_dir.unwrap_or_else(|| openssl_dir.join("include"));
(lib_dir, include_dir)
}
}
}
fn resolve_with_wellknown_homebrew_location(dir: &str) -> Option<PathBuf> {
let versions = ["openssl@3", "openssl@3.0", "openssl@1.1"];
// Check up default aarch 64 Homebrew installation location first
// for quick resolution if possible.
// `pkg-config` on brew doesn't necessarily contain settings for openssl apparently.
for version in &versions {
let homebrew = Path::new(dir).join(format!("opt/{version}"));
if homebrew.exists() {
return Some(homebrew);
}
}
for version in &versions {
// Calling `brew --prefix <package>` command usually slow and
// takes seconds, and will be used only as a last resort.
let output = execute_command_and_get_output("brew", &["--prefix", version]);
if let Some(ref output) = output {
let homebrew = Path::new(&output);
if homebrew.exists() {
return Some(homebrew.to_path_buf());
}
}
}
None
}
fn resolve_with_wellknown_location(dir: &str) -> Option<PathBuf> {
let root_dir = Path::new(dir);
let include_openssl = root_dir.join("include/openssl");
if include_openssl.exists() {
Some(root_dir.to_path_buf())
} else {
None
}
}
fn find_openssl_dir(target: &str) -> OsString {
let host = env::var("HOST").unwrap();
if host == target && target.ends_with("-apple-darwin") {
let homebrew_dir = match target {
"aarch64-apple-darwin" => "/opt/homebrew",
_ => "/usr/local",
};
if let Some(dir) = resolve_with_wellknown_homebrew_location(homebrew_dir) {
return dir.into();
} else if let Some(dir) = resolve_with_wellknown_location("/opt/pkg") {
// pkgsrc
return dir.into();
} else if let Some(dir) = resolve_with_wellknown_location("/opt/local") {
// MacPorts
return dir.into();
}
}
try_pkg_config();
try_vcpkg();
// FreeBSD, OpenBSD, and AIX ship with Libre|OpenSSL
// TODO: see of this is still needed for OpenBSD
if host == target
&& (target.contains("freebsd") || target.contains("openbsd") || target.contains("aix"))
{
return OsString::from("/usr");
}
// DragonFly has libressl (or openssl) in ports, but this doesn't include a pkg-config file
if host == target && target.contains("dragonfly") {
return OsString::from("/usr/local");
}
let msg_header =
"Could not find directory of OpenSSL installation, and this `-sys` crate cannot
proceed without this knowledge. If OpenSSL is installed and this crate had
trouble finding it, you can set the `OPENSSL_DIR` environment variable for the
compilation process.";
println!(
"cargo:warning={} See stderr section below for further information.",
msg_header.replace('\n', " ")
);
let mut msg = format!(
"
{}
Make sure you also have the development packages of openssl installed.
For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora.
If you're in a situation where you think the directory *should* be found
automatically, please open a bug at https://github.com/rust-openssl/rust-openssl
and include information about your system as well as this message.
$HOST = {}
$TARGET = {}
openssl-sys = {}
",
msg_header,
host,
target,
env!("CARGO_PKG_VERSION")
);
if host.contains("apple-darwin") && target.contains("apple-darwin") {
let system = Path::new("/usr/lib/libssl.0.9.8.dylib");
if system.exists() {
msg.push_str(
"
openssl-sys crate build failed: no supported version of OpenSSL found.
Ways to fix it:
- Use the `vendored` feature of openssl-sys crate to build OpenSSL from source.
- Use Homebrew to install the `openssl` package.
",
);
}
}
if host.contains("unknown-linux")
&& target.contains("unknown-linux-gnu")
&& Command::new("pkg-config").output().is_err()
{
msg.push_str(
"
It looks like you're compiling on Linux and also targeting Linux. Currently this
requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config`
could not be found. If you have OpenSSL installed you can likely fix this by
installing `pkg-config`.
",
);
}
if host.contains("windows") && target.contains("windows-gnu") {
msg.push_str(
"
It looks like you're compiling for MinGW but you may not have either OpenSSL or
pkg-config installed. You can install these two dependencies with:
pacman -S openssl-devel pkgconf
and try building this crate again.
",
);
}
if host.contains("windows") && target.contains("windows-msvc") {
msg.push_str(
"
It looks like you're compiling for MSVC but we couldn't detect an OpenSSL
installation. If there isn't one installed then you can try the rust-openssl
README for more information about how to download precompiled binaries of
OpenSSL:
https://github.com/rust-openssl/rust-openssl#windows
",
);
}
eprintln!("{msg}");
std::process::exit(101); // same as panic previously
}
/// Attempt to find OpenSSL through pkg-config.
///
/// Note that if this succeeds then the function does not return as pkg-config
/// typically tells us all the information that we need.
fn try_pkg_config() {
let target = env::var("TARGET").unwrap();
let host = env::var("HOST").unwrap();
// FIXME we really shouldn't be automatically enabling this
if target.contains("windows-gnu") && host.contains("windows") {
env::set_var("PKG_CONFIG_ALLOW_CROSS", "1");
} else if target.contains("windows-msvc") {
// MSVC targets use vcpkg instead.
return;
}
let lib = match pkg_config::Config::new()
.print_system_libs(false)
.probe("openssl")
{
Ok(lib) => lib,
Err(e) => {
println!("\n\nCould not find openssl via pkg-config:\n{e}\n");
return;
}
};
super::postprocess(&lib.include_paths);
for include in lib.include_paths.iter() {
println!("cargo:include={}", include.display());
}
process::exit(0);
}
/// Attempt to find OpenSSL through vcpkg.
///
/// Note that if this succeeds then the function does not return as vcpkg
/// should emit all of the cargo metadata that we need.
fn try_vcpkg() {
let target = env::var("TARGET").unwrap();
if !target.contains("windows") {
return;
}
// vcpkg will not emit any metadata if it can not find libraries
// appropriate for the target triple with the desired linkage.
let lib = match vcpkg::Config::new()
.emit_includes(true)
.find_package("openssl")
{
Ok(lib) => lib,
Err(e) => {
println!("note: vcpkg did not find openssl: {e}");
return;
}
};
super::postprocess(&lib.include_paths);
println!("cargo:rustc-link-lib=user32");
println!("cargo:rustc-link-lib=gdi32");
println!("cargo:rustc-link-lib=crypt32");
println!("cargo:rustc-link-lib=advapi32");
process::exit(0);
}
fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option<String> {
let out = Command::new(cmd).args(args).output();
if let Ok(ref r1) = out {
if r1.status.success() {
let r2 = String::from_utf8(r1.stdout.clone());
if let Ok(r3) = r2 {
return Some(r3.trim().to_string());
}
}
}
None
}

View File

@@ -0,0 +1,25 @@
use openssl_src;
use std::path::PathBuf;
use super::env;
pub fn get_openssl(_target: &str) -> (Vec<PathBuf>, PathBuf) {
let openssl_config_dir = env("OPENSSL_CONFIG_DIR");
let mut openssl_src_build = openssl_src::Build::new();
if let Some(value) = openssl_config_dir {
openssl_src_build.openssl_dir(PathBuf::from(value));
}
let artifacts = openssl_src_build.build();
println!("cargo:vendored=1");
println!(
"cargo:root={}",
artifacts.lib_dir().parent().unwrap().display()
);
(
vec![artifacts.lib_dir().to_path_buf()],
artifacts.include_dir().to_path_buf(),
)
}

View File

@@ -0,0 +1,556 @@
#[cfg(feature = "bindgen")]
extern crate bindgen;
extern crate cc;
#[cfg(feature = "vendored")]
extern crate openssl_src;
extern crate pkg_config;
extern crate vcpkg;
use std::collections::HashSet;
use std::env;
use std::ffi::OsString;
use std::path::PathBuf;
mod cfgs;
mod find_normal;
#[cfg(feature = "vendored")]
mod find_vendored;
mod run_bindgen;
#[derive(PartialEq)]
enum Version {
Openssl3xx,
Openssl11x,
Openssl10x,
Libressl,
Boringssl,
AwsLc,
}
fn env_inner(name: &str) -> Option<OsString> {
let var = env::var_os(name);
println!("cargo:rerun-if-env-changed={name}");
match var {
Some(ref v) => println!("{} = {}", name, v.to_string_lossy()),
None => println!("{name} unset"),
}
var
}
fn env(name: &str) -> Option<OsString> {
let prefix = env::var("TARGET").unwrap().to_uppercase().replace('-', "_");
let prefixed = format!("{prefix}_{name}");
env_inner(&prefixed).or_else(|| env_inner(name))
}
fn find_openssl(target: &str) -> (Vec<PathBuf>, PathBuf) {
#[cfg(feature = "vendored")]
{
// vendor if the feature is present, unless
// OPENSSL_NO_VENDOR exists and isn't `0`
if env("OPENSSL_NO_VENDOR").map_or(true, |s| s == "0") {
return find_vendored::get_openssl(target);
}
}
find_normal::get_openssl(target)
}
fn check_ssl_kind() {
if cfg!(feature = "unstable_boringssl") {
println!("cargo:rustc-cfg=boringssl");
println!("cargo:boringssl=true");
if let Ok(vars) = env::var("DEP_BSSL_CONF") {
for var in vars.split(',') {
println!("cargo:rustc-cfg=osslconf=\"{var}\"");
}
println!("cargo:conf={vars}");
}
// BoringSSL does not have any build logic, exit early
std::process::exit(0);
}
let is_aws_lc = cfg!(feature = "aws-lc");
let is_aws_lc_fips = cfg!(feature = "aws-lc-fips");
if is_aws_lc || is_aws_lc_fips {
// The aws-lc-sys crate uses a link name that embeds
// the version number of crate. Examples (crate-name => links name):
// * aws-lc-sys => aws_lc_0_26_0
// This is done to avoid issues if the cargo dependency graph for an application
// were to resolve to multiple versions for the same crate.
//
// Due to this we need to determine what version of the AWS-LC has been selected (fips or non-fips)
// and then need to parse out the pieces we are interested in ignoring the version component of the name.
let aws_lc_env_var_prefix: &'static str = if is_aws_lc_fips {
"DEP_AWS_LC_FIPS_"
} else {
"DEP_AWS_LC_"
};
println!("cargo:rustc-cfg=awslc");
println!("cargo:awslc=true");
if is_aws_lc_fips {
println!("cargo:rustc-cfg=awslc_fips");
println!("cargo:awslc_fips=true");
}
let mut version = None;
for (name, _) in std::env::vars() {
if let Some(name) = name.strip_prefix(aws_lc_env_var_prefix) {
if let Some(name) = name.strip_suffix("_INCLUDE") {
version = Some(name.to_owned());
break;
}
}
}
let version = version.expect("aws-lc version detected");
// Read the OpenSSL configuration statements and emit rust-cfg for each.
if let Ok(vars) = std::env::var(format!("{aws_lc_env_var_prefix}{version}_CONF")) {
for var in vars.split(',') {
println!("cargo:rustc-cfg=osslconf=\"{var}\"");
}
println!("cargo:conf={vars}");
}
// Emit the include header directory from the aws-lc(-fips)-sys crate so that it can be used if needed
// by crates consuming openssl-sys.
if let Ok(val) = std::env::var(format!("{aws_lc_env_var_prefix}{version}_INCLUDE")) {
println!("cargo:include={val}");
}
// AWS-LC does not have any build logic, exit early
std::process::exit(0);
}
}
fn main() {
println!("cargo:rustc-check-cfg=cfg(osslconf, values(\"OPENSSL_NO_OCB\", \"OPENSSL_NO_SM4\", \"OPENSSL_NO_SEED\", \"OPENSSL_NO_CHACHA\", \"OPENSSL_NO_CAST\", \"OPENSSL_NO_IDEA\", \"OPENSSL_NO_CAMELLIA\", \"OPENSSL_NO_RC4\", \"OPENSSL_NO_BF\", \"OPENSSL_NO_PSK\", \"OPENSSL_NO_DEPRECATED_3_0\", \"OPENSSL_NO_SCRYPT\", \"OPENSSL_NO_SM3\", \"OPENSSL_NO_RMD160\", \"OPENSSL_NO_EC2M\", \"OPENSSL_NO_OCSP\", \"OPENSSL_NO_CMS\", \"OPENSSL_NO_COMP\", \"OPENSSL_NO_SOCK\", \"OPENSSL_NO_STDIO\", \"OPENSSL_NO_EC\", \"OPENSSL_NO_SSL3_METHOD\", \"OPENSSL_NO_KRB5\", \"OPENSSL_NO_TLSEXT\", \"OPENSSL_NO_SRP\", \"OPENSSL_NO_SRTP\", \"OPENSSL_NO_RFC3779\", \"OPENSSL_NO_SHA\", \"OPENSSL_NO_NEXTPROTONEG\", \"OPENSSL_NO_ENGINE\", \"OPENSSL_NO_BUF_FREELISTS\", \"OPENSSL_NO_RC2\"))");
println!("cargo:rustc-check-cfg=cfg(openssl)");
println!("cargo:rustc-check-cfg=cfg(libressl)");
println!("cargo:rustc-check-cfg=cfg(boringssl)");
println!("cargo:rustc-check-cfg=cfg(awslc)");
println!("cargo:rustc-check-cfg=cfg(libressl250)");
println!("cargo:rustc-check-cfg=cfg(libressl251)");
println!("cargo:rustc-check-cfg=cfg(libressl252)");
println!("cargo:rustc-check-cfg=cfg(libressl261)");
println!("cargo:rustc-check-cfg=cfg(libressl270)");
println!("cargo:rustc-check-cfg=cfg(libressl271)");
println!("cargo:rustc-check-cfg=cfg(libressl273)");
println!("cargo:rustc-check-cfg=cfg(libressl280)");
println!("cargo:rustc-check-cfg=cfg(libressl281)");
println!("cargo:rustc-check-cfg=cfg(libressl291)");
println!("cargo:rustc-check-cfg=cfg(libressl310)");
println!("cargo:rustc-check-cfg=cfg(libressl321)");
println!("cargo:rustc-check-cfg=cfg(libressl332)");
println!("cargo:rustc-check-cfg=cfg(libressl340)");
println!("cargo:rustc-check-cfg=cfg(libressl350)");
println!("cargo:rustc-check-cfg=cfg(libressl360)");
println!("cargo:rustc-check-cfg=cfg(libressl361)");
println!("cargo:rustc-check-cfg=cfg(libressl370)");
println!("cargo:rustc-check-cfg=cfg(libressl380)");
println!("cargo:rustc-check-cfg=cfg(libressl381)");
println!("cargo:rustc-check-cfg=cfg(libressl382)");
println!("cargo:rustc-check-cfg=cfg(libressl390)");
println!("cargo:rustc-check-cfg=cfg(libressl400)");
println!("cargo:rustc-check-cfg=cfg(libressl410)");
println!("cargo:rustc-check-cfg=cfg(libressl420)");
println!("cargo:rustc-check-cfg=cfg(ossl101)");
println!("cargo:rustc-check-cfg=cfg(ossl102)");
println!("cargo:rustc-check-cfg=cfg(ossl102f)");
println!("cargo:rustc-check-cfg=cfg(ossl102h)");
println!("cargo:rustc-check-cfg=cfg(ossl110)");
println!("cargo:rustc-check-cfg=cfg(ossl110f)");
println!("cargo:rustc-check-cfg=cfg(ossl110g)");
println!("cargo:rustc-check-cfg=cfg(ossl110h)");
println!("cargo:rustc-check-cfg=cfg(ossl111)");
println!("cargo:rustc-check-cfg=cfg(ossl111b)");
println!("cargo:rustc-check-cfg=cfg(ossl111c)");
println!("cargo:rustc-check-cfg=cfg(ossl111d)");
println!("cargo:rustc-check-cfg=cfg(ossl300)");
println!("cargo:rustc-check-cfg=cfg(ossl310)");
println!("cargo:rustc-check-cfg=cfg(ossl320)");
println!("cargo:rustc-check-cfg=cfg(ossl330)");
println!("cargo:rustc-check-cfg=cfg(ossl340)");
check_ssl_kind();
let target = env::var("TARGET").unwrap();
let (lib_dirs, include_dir) = find_openssl(&target);
// rerun-if-changed causes openssl-sys to rebuild if the openssl include
// dir has changed since the last build. However, this causes a rebuild
// every time when vendoring so we disable it.
let potential_path = include_dir.join("openssl");
if potential_path.exists() && !cfg!(feature = "vendored") {
if let Some(printable_include) = potential_path.to_str() {
println!("cargo:rerun-if-changed={printable_include}");
}
}
if !lib_dirs.iter().all(|p| p.exists()) {
panic!("OpenSSL library directory does not exist: {lib_dirs:?}");
}
if !include_dir.exists() {
panic!(
"OpenSSL include directory does not exist: {}",
include_dir.to_string_lossy()
);
}
for lib_dir in lib_dirs.iter() {
println!(
"cargo:rustc-link-search=native={}",
lib_dir.to_string_lossy()
);
}
println!("cargo:include={}", include_dir.to_string_lossy());
let version = postprocess(&[include_dir]);
let libs_env = env("OPENSSL_LIBS");
let libs = match libs_env.as_ref().and_then(|s| s.to_str()) {
Some(v) => {
if v.is_empty() {
vec![]
} else {
v.split(':').collect()
}
}
None => match version {
Version::Openssl10x if target.contains("windows") => vec!["ssleay32", "libeay32"],
Version::Openssl3xx | Version::Openssl11x if target.contains("windows-msvc") => {
vec!["libssl", "libcrypto"]
}
_ => vec!["ssl", "crypto"],
},
};
let kind = determine_mode(&lib_dirs, &libs);
for lib in libs.into_iter() {
println!("cargo:rustc-link-lib={kind}={lib}");
}
// libssl in BoringSSL requires the C++ runtime, and static libraries do
// not carry dependency information. On unix-like platforms, the C++
// runtime and standard library are typically picked up by default via the
// C++ compiler, which has a platform-specific default. (See implementations
// of `GetDefaultCXXStdlibType` in Clang.) Builds may also choose to
// override this and specify their own with `-nostdinc++` and `-nostdlib++`
// flags. Some compilers also provide options like `-stdlib=libc++`.
//
// Typically, such information is carried all the way up the build graph,
// but Cargo is not an integrated cross-language build system, so it cannot
// safely handle any of these situations. As a result, we need to make
// guesses. Getting this wrong may result in symbol conflicts and memory
// errors, but this unsafety is inherent to driving builds with
// externally-built libraries using Cargo.
//
// For now, we guess that the build was made with the defaults. This too is
// difficult because Rust does not expose this information from Clang, but
// try to match the behavior for common platforms. For a more robust option,
// this likely needs to be deferred to the caller with an environment
// variable.
if (version == Version::Boringssl || version == Version::AwsLc)
&& kind == "static"
&& env::var("CARGO_CFG_UNIX").is_ok()
{
let cpp_lib = match env::var("CARGO_CFG_TARGET_OS").unwrap().as_ref() {
"macos" => "c++",
_ => "stdc++",
};
println!("cargo:rustc-link-lib={cpp_lib}");
}
// https://github.com/openssl/openssl/pull/15086
if version == Version::Openssl3xx
&& kind == "static"
&& (env::var("CARGO_CFG_TARGET_OS").unwrap() == "linux"
|| env::var("CARGO_CFG_TARGET_OS").unwrap() == "android")
&& env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap() == "32"
{
println!("cargo:rustc-link-lib=atomic");
}
if kind == "static" && target.contains("windows") {
println!("cargo:rustc-link-lib=dylib=gdi32");
println!("cargo:rustc-link-lib=dylib=user32");
println!("cargo:rustc-link-lib=dylib=crypt32");
println!("cargo:rustc-link-lib=dylib=ws2_32");
println!("cargo:rustc-link-lib=dylib=advapi32");
}
}
fn postprocess(include_dirs: &[PathBuf]) -> Version {
let version = validate_headers(include_dirs);
// Never run bindgen for BoringSSL or AWS-LC, if it was needed we already ran it.
if !(version == Version::Boringssl || version == Version::AwsLc) {
#[cfg(feature = "bindgen")]
run_bindgen::run(&include_dirs);
}
version
}
/// Validates the header files found in `include_dir` and then returns the
/// version string of OpenSSL.
#[allow(clippy::unusual_byte_groupings)]
fn validate_headers(include_dirs: &[PathBuf]) -> Version {
// This `*-sys` crate only works with OpenSSL 1.0.2, 1.1.0, 1.1.1 and 3.0.0.
// To correctly expose the right API from this crate, take a look at
// `opensslv.h` to see what version OpenSSL claims to be.
//
// OpenSSL has a number of build-time configuration options which affect
// various structs and such. Since OpenSSL 1.1.0 this isn't really a problem
// as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem.
//
// To handle all this conditional compilation we slurp up the configuration
// file of OpenSSL, `opensslconf.h`, and then dump out everything it defines
// as our own #[cfg] directives. That way the `ossl10x.rs` bindings can
// account for compile differences and such.
println!("cargo:rerun-if-changed=build/expando.c");
let mut gcc = cc::Build::new();
gcc.includes(include_dirs);
let expanded = match gcc.file("build/expando.c").try_expand() {
Ok(expanded) => expanded,
Err(e) => {
panic!(
"
Header expansion error:
{e:?}
Failed to find OpenSSL development headers.
You can try fixing this setting the `OPENSSL_DIR` environment variable
pointing to your OpenSSL installation or installing OpenSSL headers package
specific to your distribution:
# On Ubuntu
sudo apt-get install pkg-config libssl-dev
# On Arch Linux
sudo pacman -S pkgconf openssl
# On Fedora
sudo dnf install pkgconf perl-FindBin perl-IPC-Cmd openssl-devel
# On Alpine Linux
apk add pkgconf openssl-dev
See rust-openssl documentation for more information:
https://docs.rs/openssl
"
);
}
};
let expanded = String::from_utf8(expanded).unwrap();
let mut enabled = vec![];
let mut openssl_version = None;
let mut libressl_version = None;
let mut is_boringssl = false;
let mut is_awslc = false;
let mut bindgen_symbol_prefix: Option<String> = None;
for line in expanded.lines() {
let line = line.trim();
let openssl_prefix = "RUST_VERSION_OPENSSL_";
let new_openssl_prefix = "RUST_VERSION_NEW_OPENSSL_";
let libressl_prefix = "RUST_VERSION_LIBRESSL_";
let boringssl_prefix = "RUST_OPENSSL_IS_BORINGSSL";
let awslc_prefix = "RUST_OPENSSL_IS_AWSLC";
let conf_prefix = "RUST_CONF_";
let symbol_prefix = "RUST_BINDGEN_SYMBOL_PREFIX_";
if let Some(version) = line.strip_prefix(openssl_prefix) {
openssl_version = Some(parse_version(version));
} else if let Some(version) = line.strip_prefix(new_openssl_prefix) {
openssl_version = Some(parse_new_version(version));
} else if let Some(version) = line.strip_prefix(libressl_prefix) {
libressl_version = Some(parse_version(version));
} else if let Some(conf) = line.strip_prefix(conf_prefix) {
enabled.push(conf);
} else if line.starts_with(boringssl_prefix) {
is_boringssl = true;
} else if line.starts_with(awslc_prefix) {
is_awslc = true;
} else if line.starts_with(symbol_prefix) {
let sym_prefix = String::from(line.strip_prefix(symbol_prefix).unwrap());
bindgen_symbol_prefix = Some(sym_prefix);
}
}
for enabled in &enabled {
println!("cargo:rustc-cfg=osslconf=\"{enabled}\"");
}
println!("cargo:conf={}", enabled.join(","));
if is_boringssl {
println!("cargo:rustc-cfg=boringssl");
println!("cargo:boringssl=true");
run_bindgen::run_boringssl(include_dirs);
return Version::Boringssl;
}
if is_awslc {
println!("cargo:rustc-cfg=awslc");
println!("cargo:awslc=true");
run_bindgen::run_awslc(include_dirs, bindgen_symbol_prefix);
return Version::AwsLc;
}
// We set this for any non-BoringSSL lib.
println!("cargo:rustc-cfg=openssl");
for cfg in cfgs::get(openssl_version, libressl_version) {
println!("cargo:rustc-cfg={cfg}");
}
if let Some(libressl_version) = libressl_version {
println!("cargo:libressl_version_number={libressl_version:x}");
let major = (libressl_version >> 28) as u8;
let minor = (libressl_version >> 20) as u8;
let fix = (libressl_version >> 12) as u8;
let (major, minor, fix) = match (major, minor, fix) {
(3, 5, _) => ('3', '5', 'x'),
(3, 6, 0) => ('3', '6', '0'),
(3, 6, _) => ('3', '6', 'x'),
(3, 7, 0) => ('3', '7', '0'),
(3, 7, 1) => ('3', '7', '1'),
(3, 7, _) => ('3', '7', 'x'),
(3, 8, 0) => ('3', '8', '0'),
(3, 8, 1) => ('3', '8', '1'),
(3, 8, _) => ('3', '8', 'x'),
(3, 9, 0) => ('3', '9', '0'),
(3, 9, _) => ('3', '9', 'x'),
(4, 0, 0) => ('4', '0', '0'),
(4, 0, _) => ('4', '0', 'x'),
(4, 1, 0) => ('4', '1', '0'),
(4, 1, _) => ('4', '1', 'x'),
(4, 2, _) => ('4', '2', 'x'),
_ => version_error(),
};
println!("cargo:libressl=true");
println!("cargo:libressl_version={major}{minor}{fix}");
println!("cargo:version=101");
Version::Libressl
} else {
let openssl_version = openssl_version.unwrap();
println!("cargo:version_number={openssl_version:x}");
if openssl_version >= 0x5_00_00_00_0 {
version_error()
} else if openssl_version >= 0x3_00_00_00_0 {
Version::Openssl3xx
} else if openssl_version >= 0x1_01_01_00_0 {
println!("cargo:version=111");
Version::Openssl11x
} else if openssl_version >= 0x1_01_00_06_0 {
println!("cargo:version=110");
println!("cargo:patch=f");
Version::Openssl11x
} else if openssl_version >= 0x1_01_00_00_0 {
println!("cargo:version=110");
Version::Openssl11x
} else if openssl_version >= 0x1_00_02_00_0 {
println!("cargo:version=102");
Version::Openssl10x
} else {
version_error()
}
}
}
fn version_error() -> ! {
panic!(
"
This crate is only compatible with OpenSSL (version 1.0.2 through 1.1.1, or 3), or LibreSSL 3.5
through 4.2.x, but a different version of OpenSSL was found. The build is now aborting
due to this version mismatch.
"
);
}
// parses a string that looks like "0x100020cfL"
fn parse_version(version: &str) -> u64 {
// cut off the 0x prefix
assert!(version.starts_with("0x"));
let version = &version[2..];
// and the type specifier suffix
let version = version.trim_end_matches(|c: char| !c.is_ascii_hexdigit());
u64::from_str_radix(version, 16).unwrap()
}
// parses a string that looks like 3_0_0
fn parse_new_version(version: &str) -> u64 {
println!("version: {version}");
let mut it = version.split('_');
let major = it.next().unwrap().parse::<u64>().unwrap();
let minor = it.next().unwrap().parse::<u64>().unwrap();
let patch = it.next().unwrap().parse::<u64>().unwrap();
(major << 28) | (minor << 20) | (patch << 4)
}
/// Given a libdir for OpenSSL (where artifacts are located) as well as the name
/// of the libraries we're linking to, figure out whether we should link them
/// statically or dynamically.
fn determine_mode(libdirs: &[PathBuf], libs: &[&str]) -> &'static str {
// First see if a mode was explicitly requested
let kind = env("OPENSSL_STATIC");
match kind.as_ref().and_then(|s| s.to_str()) {
Some("0") => return "dylib",
Some(_) => return "static",
None => {}
}
// Next, see what files we actually have to link against, and see what our
// possibilities even are.
let mut files = HashSet::new();
for dir in libdirs {
for path in dir
.read_dir()
.unwrap()
.map(|e| e.unwrap())
.map(|e| e.file_name())
.filter_map(|e| e.into_string().ok())
{
files.insert(path);
}
}
let can_static = libs
.iter()
.all(|l| files.contains(&format!("lib{l}.a")) || files.contains(&format!("{l}.lib")));
let can_dylib = libs.iter().all(|l| {
files.contains(&format!("lib{l}.so"))
|| files.contains(&format!("{l}.dll"))
|| files.contains(&format!("lib{l}.dylib"))
});
match (can_static, can_dylib) {
(true, false) => return "static",
(false, true) => return "dylib",
(false, false) => {
panic!(
"OpenSSL libdir at `{libdirs:?}` does not contain the required files \
to either statically or dynamically link OpenSSL"
);
}
(true, true) => {}
}
// Ok, we've got not explicit preference and can *either* link statically or
// link dynamically. In the interest of "security upgrades" and/or "best
// practices with security libs", let's link dynamically.
"dylib"
}

View File

@@ -0,0 +1,386 @@
#[cfg(feature = "bindgen")]
use bindgen::callbacks::{ItemInfo, MacroParsingBehavior, ParseCallbacks};
#[cfg(feature = "bindgen")]
use bindgen::{MacroTypeVariation, RustTarget};
use std::io::Write;
use std::path::PathBuf;
#[cfg(not(feature = "bindgen"))]
use std::process;
use std::{env, fs};
const INCLUDES: &str = "
#include <openssl/aes.h>
#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/cmac.h>
#include <openssl/conf.h>
#include <openssl/crypto.h>
#include <openssl/dh.h>
#include <openssl/dsa.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/objects.h>
#include <openssl/opensslv.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#include <openssl/pkcs7.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/safestack.h>
#include <openssl/sha.h>
#include <openssl/ssl.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <openssl/x509v3.h>
#if !defined(OPENSSL_IS_AWSLC)
// this must be included after ssl.h for libressl!
#include <openssl/srtp.h>
#endif
#if !(defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC))
#include <openssl/cms.h>
#endif
#if !defined(OPENSSL_NO_COMP) && !(defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC))
#include <openssl/comp.h>
#endif
#if !defined(OPENSSL_IS_BORINGSSL)
#include <openssl/ocsp.h>
#endif
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
#include <openssl/kdf.h>
#endif
#if OPENSSL_VERSION_NUMBER >= 0x30000000
#include <openssl/decoder.h>
#include <openssl/encoder.h>
#include <openssl/provider.h>
#include <openssl/params.h>
#include <openssl/param_build.h>
#endif
#if OPENSSL_VERSION_NUMBER >= 0x30200000
#include <openssl/quic.h>
#endif
#if defined(LIBRESSL_VERSION_NUMBER) || defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
#include <openssl/poly1305.h>
#endif
#if defined(OPENSSL_IS_BORINGSSL)
#include <openssl/mlkem.h>
#endif
#if OPENSSL_VERSION_NUMBER >= 0x30200000
#include <openssl/thread.h>
#endif
";
#[cfg(feature = "bindgen")]
pub fn run(include_dirs: &[PathBuf]) {
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let mut builder = bindgen::builder()
.parse_callbacks(Box::new(OpensslCallbacks))
.rust_target(RustTarget::stable(70, 0).unwrap())
.ctypes_prefix("::libc")
.raw_line("use libc::*;")
.raw_line("#[cfg(windows)] use std::os::windows::raw::HANDLE;")
.raw_line("type evp_pkey_st = EVP_PKEY;")
.allowlist_file(".*[/\\\\]openssl/[^/\\\\]+\\.h")
.allowlist_recursively(false)
// libc is missing pthread_once_t on macOS
.blocklist_type("CRYPTO_ONCE")
.blocklist_function("CRYPTO_THREAD_run_once")
// we don't want to mess with va_list
.blocklist_function("BIO_vprintf")
.blocklist_function("BIO_vsnprintf")
.blocklist_function("ERR_vset_error")
.blocklist_function("ERR_add_error_vdata")
.blocklist_function("EVP_KDF_vctrl")
.blocklist_type("OSSL_FUNC_core_vset_error_fn")
.blocklist_type("OSSL_FUNC_BIO_vprintf_fn")
.blocklist_type("OSSL_FUNC_BIO_vsnprintf_fn")
// struct hostent * does not exist on Windows
.blocklist_function("BIO_gethostbyname")
// Maintain compatibility for existing enum definitions
.rustified_enum("point_conversion_form_t")
// Maintain compatibility for pre-union definitions
.blocklist_type("GENERAL_NAME")
.blocklist_type("GENERAL_NAME_st")
.blocklist_type("EVP_PKEY")
.blocklist_type("evp_pkey_st")
.layout_tests(false)
.header_contents("includes.h", INCLUDES);
for include_dir in include_dirs {
builder = builder
.clang_arg("-I")
.clang_arg(include_dir.display().to_string());
}
builder
.generate()
.unwrap()
.write_to_file(out_dir.join("bindgen.rs"))
.unwrap();
}
#[cfg(feature = "bindgen")]
pub fn run_boringssl(include_dirs: &[PathBuf]) {
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
fs::File::create(out_dir.join("boring_static_wrapper.h"))
.expect("Failed to create boring_static_wrapper.h")
.write_all(INCLUDES.as_bytes())
.expect("Failed to write contents to boring_static_wrapper.h");
let mut builder = bindgen::builder()
.rust_target(RustTarget::stable(70, 0).unwrap())
.ctypes_prefix("::libc")
.raw_line("use libc::*;")
.derive_default(false)
.enable_function_attribute_detection()
.default_macro_constant_type(MacroTypeVariation::Signed)
.rustified_enum("point_conversion_form_t")
.allowlist_file(".*[/\\\\]openssl/[^/]+\\.h")
.allowlist_recursively(false)
.blocklist_function("BIO_vsnprintf")
.blocklist_function("OPENSSL_vasprintf")
.wrap_static_fns(true)
.wrap_static_fns_path(out_dir.join("boring_static_wrapper").display().to_string())
.layout_tests(false)
.header(
out_dir
.join("boring_static_wrapper.h")
.display()
.to_string(),
);
for include_dir in include_dirs {
builder = builder
.clang_arg("-I")
.clang_arg(include_dir.display().to_string());
}
builder
.generate()
.unwrap()
.write_to_file(out_dir.join("bindgen.rs"))
.unwrap();
cc::Build::new()
.file(out_dir.join("boring_static_wrapper.c"))
.includes(include_dirs)
.compile("boring_static_wrapper");
}
#[cfg(not(feature = "bindgen"))]
pub fn run_boringssl(include_dirs: &[PathBuf]) {
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
fs::File::create(out_dir.join("boring_static_wrapper.h"))
.expect("Failed to create boring_static_wrapper.h")
.write_all(INCLUDES.as_bytes())
.expect("Failed to write contents to boring_static_wrapper.h");
let mut bindgen_cmd = process::Command::new("bindgen");
bindgen_cmd
.arg("-o")
.arg(out_dir.join("bindgen.rs"))
.arg("--rust-target=1.70")
.arg("--ctypes-prefix=::libc")
.arg("--raw-line=use libc::*;")
.arg("--no-derive-default")
.arg("--enable-function-attribute-detection")
.arg("--default-macro-constant-type=signed")
.arg("--rustified-enum=point_conversion_form_t")
.arg("--allowlist-file=.*[/\\\\]openssl/[^/]+\\.h")
.arg("--no-recursive-allowlist")
.arg("--blocklist-function=BIO_vsnprintf")
.arg("--blocklist-function=OPENSSL_vasprintf")
.arg("--experimental")
.arg("--wrap-static-fns")
.arg("--wrap-static-fns-path")
.arg(out_dir.join("boring_static_wrapper").display().to_string())
.arg("--no-layout-tests")
.arg(out_dir.join("boring_static_wrapper.h"))
.arg("--")
.arg(format!("--target={}", env::var("TARGET").unwrap()));
for include_dir in include_dirs {
bindgen_cmd.arg("-I").arg(include_dir.display().to_string());
}
let result = bindgen_cmd.status().expect("bindgen failed to execute");
assert!(result.success());
cc::Build::new()
.file(out_dir.join("boring_static_wrapper.c"))
.includes(include_dirs)
.compile("boring_static_wrapper");
}
#[cfg(feature = "bindgen")]
mod bindgen_options {
use bindgen::callbacks::{ItemInfo, ParseCallbacks};
#[derive(Debug)]
pub struct StripPrefixCallback {
remove_prefix: Option<String>,
}
impl StripPrefixCallback {
pub fn new(prefix: &str) -> StripPrefixCallback {
StripPrefixCallback {
remove_prefix: Some(prefix.to_string()),
}
}
}
impl ParseCallbacks for StripPrefixCallback {
fn generated_name_override(&self, item_info: ItemInfo<'_>) -> Option<String> {
self.remove_prefix
.as_ref()
.and_then(|s| item_info.name.strip_prefix(s.as_str()).map(String::from))
}
}
}
#[cfg(feature = "bindgen")]
pub fn run_awslc(include_dirs: &[PathBuf], symbol_prefix: Option<String>) {
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
fs::File::create(out_dir.join("awslc_static_wrapper.h"))
.expect("Failed to create awslc_static_wrapper.h")
.write_all(INCLUDES.as_bytes())
.expect("Failed to write contents to awslc_static_wrapper.h");
let mut builder = bindgen::builder()
.rust_target(RustTarget::stable(70, 0).unwrap())
.ctypes_prefix("::libc")
.raw_line("use libc::*;")
.derive_default(false)
.enable_function_attribute_detection()
.default_macro_constant_type(MacroTypeVariation::Signed)
.rustified_enum("point_conversion_form_t")
.allowlist_file(r".*(/|\\)openssl((/|\\)[^/\\]+)+\.h")
.wrap_static_fns(true)
.wrap_static_fns_path(out_dir.join("awslc_static_wrapper").display().to_string())
.layout_tests(false)
.header(out_dir.join("awslc_static_wrapper.h").display().to_string());
if let Some(prefix) = symbol_prefix {
use bindgen_options::StripPrefixCallback;
let callback = StripPrefixCallback::new(prefix.as_str());
builder = builder.parse_callbacks(Box::from(callback));
}
for include_dir in include_dirs {
builder = builder
.clang_arg("-I")
.clang_arg(include_dir.display().to_string());
}
builder
.generate()
.unwrap()
.write_to_file(out_dir.join("bindgen.rs"))
.unwrap();
cc::Build::new()
.file(out_dir.join("awslc_static_wrapper.c"))
.includes(include_dirs)
.compile("awslc_static_wrapper");
}
#[cfg(not(feature = "bindgen"))]
pub fn run_awslc(include_dirs: &[PathBuf], symbol_prefix: Option<String>) {
if symbol_prefix.is_some() {
panic!("aws-lc installation has prefixed symbols, but bindgen-cli does not support removing prefixes. \
Enable the bindgen crate feature to support this installation.")
}
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
fs::File::create(out_dir.join("awslc_static_wrapper.h"))
.expect("Failed to create awslc_static_wrapper.h")
.write_all(INCLUDES.as_bytes())
.expect("Failed to write contents to awslc_static_wrapper.h");
let mut bindgen_cmd = process::Command::new("bindgen");
bindgen_cmd
.arg("-o")
.arg(out_dir.join("bindgen.rs"))
.arg("--rust-target=1.70")
.arg("--ctypes-prefix=::libc")
.arg("--raw-line=use libc::*;")
.arg("--no-derive-default")
.arg("--enable-function-attribute-detection")
.arg("--default-macro-constant-type=signed")
.arg("--rustified-enum=point_conversion_form_t")
.arg(r"--allowlist-file=.*(/|\\)openssl((/|\\)[^/\\]+)+\.h")
.arg("--experimental")
.arg("--wrap-static-fns")
.arg("--wrap-static-fns-path")
.arg(out_dir.join("awslc_static_wrapper").display().to_string())
.arg(out_dir.join("awslc_static_wrapper.h"))
.arg("--")
.arg(format!("--target={}", env::var("TARGET").unwrap()));
for include_dir in include_dirs {
bindgen_cmd.arg("-I").arg(include_dir.display().to_string());
}
let result = bindgen_cmd.status().expect("bindgen failed to execute");
assert!(result.success());
cc::Build::new()
.file(out_dir.join("awslc_static_wrapper.c"))
.includes(include_dirs)
.compile("awslc_static_wrapper");
}
#[cfg(feature = "bindgen")]
#[derive(Debug)]
struct OpensslCallbacks;
#[cfg(feature = "bindgen")]
impl ParseCallbacks for OpensslCallbacks {
// for now we'll continue hand-writing constants
fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior {
MacroParsingBehavior::Ignore
}
fn item_name(&self, item_info: ItemInfo) -> Option<String> {
match item_info.name {
// Our original definitions of these are wrong, so rename to avoid breakage
"CRYPTO_EX_new"
| "CRYPTO_EX_dup"
| "CRYPTO_EX_free"
| "BIO_meth_set_write"
| "BIO_meth_set_read"
| "BIO_meth_set_puts"
| "BIO_meth_set_ctrl"
| "BIO_meth_set_create"
| "BIO_meth_set_destroy"
| "CRYPTO_set_locking_callback"
| "CRYPTO_set_id_callback"
| "SSL_CTX_set_tmp_dh_callback"
| "SSL_set_tmp_dh_callback"
| "SSL_CTX_set_tmp_ecdh_callback"
| "SSL_set_tmp_ecdh_callback"
| "SSL_CTX_callback_ctrl"
| "SSL_CTX_set_alpn_select_cb" => Some(format!("{}__fixed_rust", item_info.name)),
// On NetBSD, "off_t" is generated as "__off_t".
"__off_t" => Some("off_t".to_string()),
_ => None,
}
}
}

View File

@@ -0,0 +1,10 @@
use cratecrate::cratecrate::crate::libc::*;
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
pub const AES_ENCRYPT: c_int = 1;
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
pub const AES_DECRYPT: c_int = 0;
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
pub const AES_MAXNR: c_int = 14;
pub const AES_BLOCK_SIZE: c_int = 16;

View File

@@ -0,0 +1,39 @@
use cratecrate::cratecrate::crate::libc::*;
use super::*;
// ASN.1 tag values
pub const V_ASN1_EOC: c_int = 0;
pub const V_ASN1_BOOLEAN: c_int = 1;
pub const V_ASN1_INTEGER: c_int = 2;
pub const V_ASN1_BIT_STRING: c_int = 3;
pub const V_ASN1_OCTET_STRING: c_int = 4;
pub const V_ASN1_NULL: c_int = 5;
pub const V_ASN1_OBJECT: c_int = 6;
pub const V_ASN1_OBJECT_DESCRIPTOR: c_int = 7;
pub const V_ASN1_EXTERNAL: c_int = 8;
pub const V_ASN1_REAL: c_int = 9;
pub const V_ASN1_ENUMERATED: c_int = 10;
pub const V_ASN1_UTF8STRING: c_int = 12;
pub const V_ASN1_SEQUENCE: c_int = 16;
pub const V_ASN1_SET: c_int = 17;
pub const V_ASN1_NUMERICSTRING: c_int = 18;
pub const V_ASN1_PRINTABLESTRING: c_int = 19;
pub const V_ASN1_T61STRING: c_int = 20;
pub const V_ASN1_TELETEXSTRING: c_int = 20; // alias
pub const V_ASN1_VIDEOTEXSTRING: c_int = 21;
pub const V_ASN1_IA5STRING: c_int = 22;
pub const V_ASN1_UTCTIME: c_int = 23;
pub const V_ASN1_GENERALIZEDTIME: c_int = 24;
pub const V_ASN1_GRAPHICSTRING: c_int = 25;
pub const V_ASN1_ISO64STRING: c_int = 26;
pub const V_ASN1_VISIBLESTRING: c_int = 26; // alias
pub const V_ASN1_GENERALSTRING: c_int = 27;
pub const V_ASN1_UNIVERSALSTRING: c_int = 28;
pub const V_ASN1_BMPSTRING: c_int = 30;
pub const MBSTRING_FLAG: c_int = 0x1000;
pub const MBSTRING_UTF8: c_int = MBSTRING_FLAG;
pub const MBSTRING_ASC: c_int = MBSTRING_FLAG | 1;
pub const MBSTRING_BMP: c_int = MBSTRING_FLAG | 2;
pub const MBSTRING_UNIV: c_int = MBSTRING_FLAG | 4;

View File

@@ -0,0 +1,116 @@
use cratecrate::cratecrate::crate::libc::*;
use super::*;
pub const BIO_TYPE_NONE: c_int = 0;
pub const BIO_CTRL_EOF: c_int = 2;
pub const BIO_CTRL_INFO: c_int = 3;
pub const BIO_CTRL_FLUSH: c_int = 11;
pub const BIO_CTRL_DGRAM_QUERY_MTU: c_int = 40;
pub const BIO_C_SET_BUF_MEM_EOF_RETURN: c_int = 130;
pub unsafe fn BIO_set_retry_read(b: *mut BIO) {
BIO_set_flags(b, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY)
}
pub unsafe fn BIO_set_retry_write(b: *mut BIO) {
BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY)
}
pub unsafe fn BIO_clear_retry_flags(b: *mut BIO) {
BIO_clear_flags(b, BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY)
}
pub const BIO_FLAGS_READ: c_int = 0x01;
pub const BIO_FLAGS_WRITE: c_int = 0x02;
pub const BIO_FLAGS_IO_SPECIAL: c_int = 0x04;
pub const BIO_FLAGS_RWS: c_int = BIO_FLAGS_READ | BIO_FLAGS_WRITE | BIO_FLAGS_IO_SPECIAL;
pub const BIO_FLAGS_SHOULD_RETRY: c_int = 0x08;
pub unsafe fn BIO_get_mem_data(b: *mut BIO, pp: *mut *mut c_char) -> c_long {
BIO_ctrl(b, BIO_CTRL_INFO, 0, pp as *mut c_void)
}
extern "C" {
#[deprecated(note = "use BIO_meth_set_write__fixed_rust instead")]
#[cfg(any(ossl110, libressl))]
pub fn BIO_meth_set_write(
biom: *mut BIO_METHOD,
write: unsafe extern "C" fn(*mut BIO, *const c_char, c_int) -> c_int,
) -> c_int;
#[deprecated(note = "use BIO_meth_set_read__fixed_rust instead")]
#[cfg(any(ossl110, libressl))]
pub fn BIO_meth_set_read(
biom: *mut BIO_METHOD,
read: unsafe extern "C" fn(*mut BIO, *mut c_char, c_int) -> c_int,
) -> c_int;
#[deprecated(note = "use BIO_meth_set_puts__fixed_rust instead")]
#[cfg(any(ossl110, libressl))]
pub fn BIO_meth_set_puts(
biom: *mut BIO_METHOD,
read: unsafe extern "C" fn(*mut BIO, *const c_char) -> c_int,
) -> c_int;
#[deprecated(note = "use BIO_meth_set_ctrl__fixed_rust instead")]
#[cfg(any(ossl110, libressl))]
pub fn BIO_meth_set_ctrl(
biom: *mut BIO_METHOD,
read: unsafe extern "C" fn(*mut BIO, c_int, c_long, *mut c_void) -> c_long,
) -> c_int;
#[deprecated(note = "use BIO_meth_set_create__fixed_rust instead")]
#[cfg(any(ossl110, libressl))]
pub fn BIO_meth_set_create(
biom: *mut BIO_METHOD,
create: unsafe extern "C" fn(*mut BIO) -> c_int,
) -> c_int;
#[deprecated(note = "use BIO_meth_set_destroy__fixed_rust instead")]
#[cfg(any(ossl110, libressl))]
pub fn BIO_meth_set_destroy(
biom: *mut BIO_METHOD,
destroy: unsafe extern "C" fn(*mut BIO) -> c_int,
) -> c_int;
}
cfg_if! {
if #[cfg(ossl320)] {
use std::ptr;
pub const BIO_CTRL_DGRAM_GET_MTU: c_int = 41;
pub const BIO_CTRL_DGRAM_SET_MTU: c_int = 42;
pub const BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP: c_int = 82;
pub const BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE: c_int = 83;
pub const BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE: c_int = 84;
pub const BIO_CTRL_DGRAM_GET_CAPS: c_int = 86;
pub const BIO_CTRL_DGRAM_SET_CAPS: c_int = 87;
pub const BIO_CTRL_DGRAM_GET_NO_TRUNC: c_int = 88;
pub const BIO_CTRL_DGRAM_SET_NO_TRUNC: c_int = 89;
pub unsafe fn BIO_dgram_get_no_trunc(bio: *mut BIO) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_NO_TRUNC, 0, ptr::null_mut()) as c_int
}
pub unsafe fn BIO_dgram_set_no_trunc(bio: *mut BIO, enable: c_int) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_NO_TRUNC, enable as c_long, ptr::null_mut()) as c_int
}
pub unsafe fn BIO_dgram_get_cap(bio: *mut BIO) -> u32 {
BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_CAPS, 0, ptr::null_mut()) as u32
}
pub unsafe fn BIO_dgram_set_cap(bio: *mut BIO, cap: u32) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_CAPS, cap as c_long, ptr::null_mut()) as c_int
}
pub unsafe fn BIO_dgram_get_local_addr_cap(bio: *mut BIO) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP, 0, ptr::null_mut()) as c_int
}
pub unsafe fn BIO_dgram_get_local_addr_enable(bio: *mut BIO, enable: *mut c_int) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE, 0, enable as *mut c_void) as c_int
}
pub unsafe fn BIO_dgram_set_local_addr_enable(bio: *mut BIO, enable: c_int) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE, enable as c_long, ptr::null_mut()) as c_int
}
pub unsafe fn BIO_dgram_get_mtu(bio: *mut BIO) -> c_uint {
BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_MTU, 0, ptr::null_mut()) as c_uint
}
pub unsafe fn BIO_dgram_set_mtu(bio: *mut BIO, mtu: c_uint) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_MTU, mtu as c_long, ptr::null_mut()) as c_int
}
}
}

View File

@@ -0,0 +1,15 @@
use cratecrate::cratecrate::crate::libc::*;
#[cfg(target_pointer_width = "64")]
pub type BN_ULONG = c_ulonglong;
#[cfg(target_pointer_width = "32")]
pub type BN_ULONG = c_uint;
#[cfg(ossl110)]
pub const BN_FLG_MALLOCED: c_int = 0x01;
#[cfg(ossl110)]
pub const BN_FLG_STATIC_DATA: c_int = 0x02;
#[cfg(ossl110)]
pub const BN_FLG_CONSTTIME: c_int = 0x04;
#[cfg(ossl110)]
pub const BN_FLG_SECURE: c_int = 0x08;

View File

@@ -0,0 +1,25 @@
use cratecrate::cratecrate::crate::libc::*;
pub const CMS_TEXT: c_uint = 0x1;
pub const CMS_NOCERTS: c_uint = 0x2;
pub const CMS_NO_CONTENT_VERIFY: c_uint = 0x4;
pub const CMS_NO_ATTR_VERIFY: c_uint = 0x8;
pub const CMS_NOSIGS: c_uint = 0x4 | 0x8;
pub const CMS_NOINTERN: c_uint = 0x10;
pub const CMS_NO_SIGNER_CERT_VERIFY: c_uint = 0x20;
pub const CMS_NOVERIFY: c_uint = 0x20;
pub const CMS_DETACHED: c_uint = 0x40;
pub const CMS_BINARY: c_uint = 0x80;
pub const CMS_NOATTR: c_uint = 0x100;
pub const CMS_NOSMIMECAP: c_uint = 0x200;
pub const CMS_NOOLDMIMETYPE: c_uint = 0x400;
pub const CMS_CRLFEOL: c_uint = 0x800;
pub const CMS_STREAM: c_uint = 0x1000;
pub const CMS_NOCRL: c_uint = 0x2000;
pub const CMS_PARTIAL: c_uint = 0x4000;
pub const CMS_REUSE_DIGEST: c_uint = 0x8000;
pub const CMS_USE_KEYID: c_uint = 0x10000;
pub const CMS_DEBUG_DECRYPT: c_uint = 0x20000;
pub const CMS_KEY_PARAM: c_uint = 0x40000;
#[cfg(any(ossl110, libressl))]
pub const CMS_ASCIICRLF: c_uint = 0x80000;

View File

@@ -0,0 +1,11 @@
use super::*;
use cratecrate::cratecrate::crate::libc::*;
/* OpenSSL 3.* only */
pub const OSSL_KEYMGMT_SELECT_PRIVATE_KEY: c_int = 0x01;
pub const OSSL_KEYMGMT_SELECT_PUBLIC_KEY: c_int = 0x02;
pub const OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS: c_int = 0x04;
pub const OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS: c_int = 0x80;
pub const OSSL_KEYMGMT_SELECT_ALL_PARAMETERS: c_int =
OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS | OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS;

View File

@@ -0,0 +1,135 @@
use super::*;
use cratecrate::cratecrate::crate::libc::*;
extern "C" {
#[deprecated(note = "use CRYPTO_set_locking_callback__fixed_rust instead")]
#[cfg(not(ossl110))]
pub fn CRYPTO_set_locking_callback(
func: unsafe extern "C" fn(mode: c_int, n: c_int, file: *const c_char, line: c_int),
);
#[deprecated(note = "use CRYPTO_set_id_callback__fixed_rust instead")]
#[cfg(not(ossl110))]
pub fn CRYPTO_set_id_callback(func: unsafe extern "C" fn() -> c_ulong);
}
cfg_if! {
if #[cfg(ossl110)] {
type CRYPTO_EX_new_ret = ();
type CRYPTO_EX_dup_from = *const CRYPTO_EX_DATA;
} else {
type CRYPTO_EX_new_ret = c_int;
type CRYPTO_EX_dup_from = *mut CRYPTO_EX_DATA;
}
}
cfg_if! {
if #[cfg(ossl300)] {
type CRYPTO_EX_dup_from_d = *mut *mut c_void;
} else {
type CRYPTO_EX_dup_from_d = *mut c_void;
}
}
// FIXME should be options
pub type CRYPTO_EX_new = unsafe extern "C" fn(
parent: *mut c_void,
ptr: *mut c_void,
ad: *mut CRYPTO_EX_DATA,
idx: c_int,
argl: c_long,
argp: *mut c_void,
) -> CRYPTO_EX_new_ret;
pub type CRYPTO_EX_dup = unsafe extern "C" fn(
to: *mut CRYPTO_EX_DATA,
from: CRYPTO_EX_dup_from,
from_d: CRYPTO_EX_dup_from_d,
idx: c_int,
argl: c_long,
argp: *mut c_void,
) -> c_int;
pub type CRYPTO_EX_free = unsafe extern "C" fn(
parent: *mut c_void,
ptr: *mut c_void,
ad: *mut CRYPTO_EX_DATA,
idx: c_int,
argl: c_long,
argp: *mut c_void,
);
#[cfg(any(ossl110, libressl390))]
#[inline]
#[track_caller]
pub unsafe fn OPENSSL_malloc(num: usize) -> *mut c_void {
CRYPTO_malloc(
num,
concat!(file!(), "\0").as_ptr() as *const _,
line!() as _,
)
}
#[cfg(not(any(ossl110, libressl390)))]
#[inline]
#[track_caller]
pub unsafe fn OPENSSL_malloc(num: c_int) -> *mut c_void {
CRYPTO_malloc(
num,
concat!(file!(), "\0").as_ptr() as *const _,
line!() as _,
)
}
#[cfg(any(ossl110, libressl390))]
#[inline]
#[track_caller]
pub unsafe fn OPENSSL_free(addr: *mut c_void) {
CRYPTO_free(
addr,
concat!(file!(), "\0").as_ptr() as *const _,
line!() as _,
)
}
#[cfg(not(any(ossl110, libressl390)))]
#[inline]
pub unsafe fn OPENSSL_free(addr: *mut c_void) {
CRYPTO_free(addr)
}
#[cfg(not(ossl110))]
pub const CRYPTO_LOCK_X509: c_int = 3;
#[cfg(not(ossl110))]
pub const CRYPTO_LOCK_EVP_PKEY: c_int = 10;
#[cfg(not(ossl110))]
pub const CRYPTO_LOCK_SSL_CTX: c_int = 12;
#[cfg(not(ossl110))]
pub const CRYPTO_LOCK_SSL_SESSION: c_int = 14;
cfg_if! {
if #[cfg(any(ossl110, libressl381))] {
pub const CRYPTO_EX_INDEX_SSL: c_int = 0;
pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 1;
} else if #[cfg(libressl)] {
pub const CRYPTO_EX_INDEX_SSL: c_int = 1;
pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 2;
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl))] {
pub const OPENSSL_VERSION: c_int = 0;
pub const OPENSSL_CFLAGS: c_int = 1;
pub const OPENSSL_BUILT_ON: c_int = 2;
pub const OPENSSL_PLATFORM: c_int = 3;
pub const OPENSSL_DIR: c_int = 4;
} else {
pub const SSLEAY_VERSION: c_int = 0;
pub const SSLEAY_CFLAGS: c_int = 2;
pub const SSLEAY_BUILT_ON: c_int = 3;
pub const SSLEAY_PLATFORM: c_int = 4;
pub const SSLEAY_DIR: c_int = 5;
}
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
pub const CRYPTO_LOCK: c_int = 1;

View File

@@ -0,0 +1,32 @@
use cratecrate::cratecrate::crate::libc::*;
use std::ptr;
use super::super::*;
cfg_if! {
if #[cfg(not(ossl300))] {
pub unsafe fn EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx: *mut EVP_PKEY_CTX, len: c_int) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
EVP_PKEY_DH,
EVP_PKEY_OP_PARAMGEN,
EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN,
len,
ptr::null_mut(),
)
}
pub unsafe fn EVP_PKEY_CTX_set_dh_paramgen_generator(ctx: *mut EVP_PKEY_CTX, gen: c_int) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
EVP_PKEY_DH,
EVP_PKEY_OP_PARAMGEN,
EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR,
gen,
ptr::null_mut(),
)
}
}
}
pub const EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN: c_int = EVP_PKEY_ALG_CTRL + 1;
pub const EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: c_int = EVP_PKEY_ALG_CTRL + 2;

View File

@@ -0,0 +1,21 @@
use cratecrate::cratecrate::crate::libc::*;
use std::ptr;
use super::super::*;
cfg_if! {
if #[cfg(not(ossl300))] {
pub unsafe fn EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx: *mut EVP_PKEY_CTX, nbits: c_int) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
EVP_PKEY_DSA,
EVP_PKEY_OP_PARAMGEN,
EVP_PKEY_CTRL_DSA_PARAMGEN_BITS,
nbits,
ptr::null_mut(),
)
}
pub const EVP_PKEY_CTRL_DSA_PARAMGEN_BITS: c_int = EVP_PKEY_ALG_CTRL + 1;
}
}

View File

@@ -0,0 +1,9 @@
use cratecrate::cratecrate::crate::libc::*;
cfg_if! {
if #[cfg(ossl300)] {
pub const DTLS1_COOKIE_LENGTH: c_uint = 255;
} else {
pub const DTLS1_COOKIE_LENGTH: c_uint = 256;
}
}

View File

@@ -0,0 +1,32 @@
use cratecrate::cratecrate::crate::libc::*;
use std::ptr;
use super::*;
pub const OPENSSL_EC_NAMED_CURVE: c_int = 1;
cfg_if! {
if #[cfg(not(ossl300))] {
pub unsafe fn EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx: *mut EVP_PKEY_CTX, nid: c_int) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
EVP_PKEY_EC,
EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID,
nid,
ptr::null_mut(),
)
}
}
}
#[cfg(ossl300)]
pub unsafe fn EVP_EC_gen(curve: *const c_char) -> *mut EVP_PKEY {
EVP_PKEY_Q_keygen(
ptr::null_mut(),
ptr::null_mut(),
"EC\0".as_ptr().cast(),
curve,
)
}
pub const EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: c_int = EVP_PKEY_ALG_CTRL + 1;

View File

@@ -0,0 +1,66 @@
use cratecrate::cratecrate::crate::libc::*;
pub const ERR_TXT_MALLOCED: c_int = 0x01;
pub const ERR_TXT_STRING: c_int = 0x02;
pub const ERR_LIB_SYS: c_int = 2;
pub const ERR_LIB_PEM: c_int = 9;
pub const ERR_LIB_ASN1: c_int = 13;
cfg_if! {
if #[cfg(ossl300)] {
pub const ERR_SYSTEM_FLAG: c_ulong = c_int::MAX as c_ulong + 1;
pub const ERR_SYSTEM_MASK: c_ulong = c_int::MAX as c_ulong;
pub const ERR_LIB_OFFSET: c_ulong = 23;
pub const ERR_LIB_MASK: c_ulong = 0xff;
pub const ERR_RFLAGS_OFFSET: c_ulong = 18;
pub const ERR_RFLAGS_MASK: c_ulong = 0x1f;
pub const ERR_REASON_MASK: c_ulong = 0x7FFFFF;
pub const ERR_RFLAG_FATAL: c_ulong = 0x1 << ERR_RFLAGS_OFFSET;
pub const fn ERR_SYSTEM_ERROR(errcode: c_ulong) -> bool {
errcode & ERR_SYSTEM_FLAG != 0
}
pub const fn ERR_GET_LIB(errcode: c_ulong) -> c_int {
// hacks since `if` isn't yet stable in const functions :(
((ERR_LIB_SYS as c_ulong * (ERR_SYSTEM_ERROR(errcode) as c_ulong)) |
(((errcode >> ERR_LIB_OFFSET) & ERR_LIB_MASK) * (!ERR_SYSTEM_ERROR(errcode) as c_ulong))) as c_int
}
pub const fn ERR_GET_FUNC(_errcode: c_ulong) -> c_int {
0
}
pub const fn ERR_GET_REASON(errcode: c_ulong) -> c_int {
// hacks since `if` isn't yet stable in const functions :(
((ERR_LIB_SYS as c_ulong * (ERR_SYSTEM_ERROR(errcode) as c_ulong)) |
((errcode & ERR_REASON_MASK) * (!ERR_SYSTEM_ERROR(errcode) as c_ulong))) as c_int
}
pub const fn ERR_PACK(lib: c_int, _func: c_int, reason: c_int) -> c_ulong {
((lib as c_ulong & ERR_LIB_MASK) << ERR_LIB_OFFSET) |
(reason as c_ulong & ERR_REASON_MASK)
}
} else {
pub const fn ERR_PACK(l: c_int, f: c_int, r: c_int) -> c_ulong {
((l as c_ulong & 0x0FF) << 24) |
((f as c_ulong & 0xFFF) << 12) |
(r as c_ulong & 0xFFF)
}
pub const fn ERR_GET_LIB(l: c_ulong) -> c_int {
((l >> 24) & 0x0FF) as c_int
}
pub const fn ERR_GET_FUNC(l: c_ulong) -> c_int {
((l >> 12) & 0xFFF) as c_int
}
pub const fn ERR_GET_REASON(l: c_ulong) -> c_int {
(l & 0xFFF) as c_int
}
}
}

View File

@@ -0,0 +1,356 @@
use super::*;
use cratecrate::cratecrate::crate::libc::*;
pub const EVP_MAX_MD_SIZE: c_uint = 64;
pub const PKCS5_SALT_LEN: c_int = 8;
pub const PKCS12_DEFAULT_ITER: c_int = 2048;
pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption;
#[cfg(any(ossl111, libressl, boringssl, awslc))]
pub const EVP_PKEY_RSA_PSS: c_int = NID_rsassaPss;
pub const EVP_PKEY_DSA: c_int = NID_dsa;
pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement;
#[cfg(ossl110)]
pub const EVP_PKEY_DHX: c_int = NID_dhpublicnumber;
pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey;
#[cfg(ossl111)]
pub const EVP_PKEY_SM2: c_int = NID_sm2;
#[cfg(any(ossl111, libressl370))]
pub const EVP_PKEY_X25519: c_int = NID_X25519;
#[cfg(any(ossl111, libressl370))]
pub const EVP_PKEY_ED25519: c_int = NID_ED25519;
#[cfg(ossl111)]
pub const EVP_PKEY_X448: c_int = NID_X448;
#[cfg(ossl111)]
pub const EVP_PKEY_ED448: c_int = NID_ED448;
pub const EVP_PKEY_HMAC: c_int = NID_hmac;
pub const EVP_PKEY_CMAC: c_int = NID_cmac;
#[cfg(ossl111)]
pub const EVP_PKEY_POLY1305: c_int = NID_poly1305;
#[cfg(any(ossl110, libressl360))]
pub const EVP_PKEY_HKDF: c_int = NID_hkdf;
#[cfg(ossl102)]
pub const EVP_CIPHER_CTX_FLAG_WRAP_ALLOW: c_int = 0x1;
pub const EVP_CTRL_GCM_SET_IVLEN: c_int = 0x9;
pub const EVP_CTRL_GCM_GET_TAG: c_int = 0x10;
pub const EVP_CTRL_GCM_SET_TAG: c_int = 0x11;
cfg_if! {
if #[cfg(ossl300)] {
pub const EVP_PKEY_KEY_PARAMETERS: c_int = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
pub const EVP_PKEY_PRIVATE_KEY: c_int = EVP_PKEY_KEY_PARAMETERS | OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
pub const EVP_PKEY_PUBLIC_KEY: c_int = EVP_PKEY_KEY_PARAMETERS | OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
pub const EVP_PKEY_KEYPAIR: c_int = EVP_PKEY_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
}
}
pub unsafe fn EVP_get_digestbynid(type_: c_int) -> *const EVP_MD {
EVP_get_digestbyname(OBJ_nid2sn(type_))
}
cfg_if! {
if #[cfg(ossl300)] {
#[inline]
pub unsafe fn EVP_MD_CTX_md(ctx: *const EVP_MD_CTX) -> *const EVP_MD {
EVP_MD_CTX_get0_md(ctx)
}
#[inline]
pub unsafe fn EVP_MD_CTX_get_size(ctx: *const EVP_MD_CTX) -> c_int {
EVP_MD_get_size(EVP_MD_CTX_get0_md(ctx))
}
#[inline]
pub unsafe fn EVP_MD_CTX_size(ctx: *const EVP_MD_CTX) -> c_int {
EVP_MD_CTX_get_size(ctx)
}
#[inline]
pub unsafe fn EVP_MD_block_size(md: *const EVP_MD) -> c_int {
EVP_MD_get_block_size(md)
}
#[inline]
pub unsafe fn EVP_MD_size(md: *const EVP_MD) -> c_int {
EVP_MD_get_size(md)
}
#[inline]
pub unsafe fn EVP_MD_type(md: *const EVP_MD) -> c_int {
EVP_MD_get_type(md)
}
#[inline]
pub unsafe fn EVP_CIPHER_key_length(cipher: *const EVP_CIPHER) -> c_int {
EVP_CIPHER_get_key_length(cipher)
}
#[inline]
pub unsafe fn EVP_CIPHER_block_size(cipher: *const EVP_CIPHER) -> c_int {
EVP_CIPHER_get_block_size(cipher)
}
#[inline]
pub unsafe fn EVP_CIPHER_iv_length(cipher: *const EVP_CIPHER) -> c_int {
EVP_CIPHER_get_iv_length(cipher)
}
#[inline]
pub unsafe fn EVP_CIPHER_nid(cipher: *const EVP_CIPHER) -> c_int {
EVP_CIPHER_get_nid(cipher)
}
#[inline]
pub unsafe fn EVP_CIPHER_CTX_block_size(ctx: *const EVP_CIPHER_CTX) -> c_int {
EVP_CIPHER_CTX_get_block_size(ctx)
}
#[inline]
pub unsafe fn EVP_CIPHER_CTX_key_length(ctx: *const EVP_CIPHER_CTX) -> c_int {
EVP_CIPHER_CTX_get_key_length(ctx)
}
#[inline]
pub unsafe fn EVP_CIPHER_CTX_iv_length(ctx: *const EVP_CIPHER_CTX) -> c_int {
EVP_CIPHER_CTX_get_iv_length(ctx)
}
#[inline]
pub unsafe fn EVP_CIPHER_CTX_num(ctx: *const EVP_CIPHER_CTX) -> c_int {
EVP_CIPHER_CTX_get_num(ctx)
}
} else {
pub unsafe fn EVP_MD_CTX_size(ctx: *const EVP_MD_CTX) -> c_int {
EVP_MD_size(EVP_MD_CTX_md(ctx))
}
}
}
#[cfg(not(ossl300))]
#[inline]
pub unsafe fn EVP_DigestSignUpdate(
ctx: *mut EVP_MD_CTX,
data: *const c_void,
dsize: size_t,
) -> c_int {
EVP_DigestUpdate(ctx, data, dsize)
}
#[cfg(not(ossl300))]
#[inline]
pub unsafe fn EVP_DigestVerifyUpdate(
ctx: *mut EVP_MD_CTX,
data: *const c_void,
dsize: size_t,
) -> c_int {
EVP_DigestUpdate(ctx, data, dsize)
}
#[cfg(ossl300)]
#[inline]
pub unsafe fn EVP_PKEY_size(pkey: *const EVP_PKEY) -> c_int {
EVP_PKEY_get_size(pkey)
}
cfg_if! {
if #[cfg(ossl300)] {
#[inline]
pub unsafe fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> c_int {
EVP_PKEY_get_id(pkey)
}
#[inline]
pub unsafe fn EVP_PKEY_bits(pkey: *const EVP_PKEY) -> c_int {
EVP_PKEY_get_bits(pkey)
}
#[inline]
pub unsafe fn EVP_PKEY_security_bits(pkey: *const EVP_PKEY) -> c_int {
EVP_PKEY_get_security_bits(pkey)
}
}
}
pub const EVP_PKEY_OP_PARAMGEN: c_int = 1 << 1;
pub const EVP_PKEY_OP_KEYGEN: c_int = 1 << 2;
cfg_if! {
if #[cfg(ossl300)] {
pub const EVP_PKEY_OP_SIGN: c_int = 1 << 4;
pub const EVP_PKEY_OP_VERIFY: c_int = 1 << 5;
pub const EVP_PKEY_OP_VERIFYRECOVER: c_int = 1 << 6;
pub const EVP_PKEY_OP_SIGNCTX: c_int = 1 << 7;
pub const EVP_PKEY_OP_VERIFYCTX: c_int = 1 << 8;
pub const EVP_PKEY_OP_ENCRYPT: c_int = 1 << 9;
pub const EVP_PKEY_OP_DECRYPT: c_int = 1 << 10;
pub const EVP_PKEY_OP_DERIVE: c_int = 1 << 11;
} else {
pub const EVP_PKEY_OP_SIGN: c_int = 1 << 3;
pub const EVP_PKEY_OP_VERIFY: c_int = 1 << 4;
pub const EVP_PKEY_OP_VERIFYRECOVER: c_int = 1 << 5;
pub const EVP_PKEY_OP_SIGNCTX: c_int = 1 << 6;
pub const EVP_PKEY_OP_VERIFYCTX: c_int = 1 << 7;
pub const EVP_PKEY_OP_ENCRYPT: c_int = 1 << 8;
pub const EVP_PKEY_OP_DECRYPT: c_int = 1 << 9;
pub const EVP_PKEY_OP_DERIVE: c_int = 1 << 10;
}
}
#[cfg(ossl340)]
pub const EVP_PKEY_OP_SIGNMSG: c_int = 1 << 14;
#[cfg(ossl340)]
pub const EVP_PKEY_OP_VERIFYMSG: c_int = 1 << 15;
cfg_if! {
if #[cfg(ossl340)] {
pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN
| EVP_PKEY_OP_SIGNMSG
| EVP_PKEY_OP_VERIFY
| EVP_PKEY_OP_VERIFYMSG
| EVP_PKEY_OP_VERIFYRECOVER
| EVP_PKEY_OP_SIGNCTX
| EVP_PKEY_OP_VERIFYCTX;
} else {
pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN
| EVP_PKEY_OP_VERIFY
| EVP_PKEY_OP_VERIFYRECOVER
| EVP_PKEY_OP_SIGNCTX
| EVP_PKEY_OP_VERIFYCTX;
}
}
pub const EVP_PKEY_OP_TYPE_CRYPT: c_int = EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT;
pub const EVP_PKEY_CTRL_MD: c_int = 1;
pub const EVP_PKEY_CTRL_SET_MAC_KEY: c_int = 6;
pub const EVP_PKEY_CTRL_CIPHER: c_int = 12;
pub const EVP_PKEY_ALG_CTRL: c_int = 0x1000;
#[cfg(any(ossl111, libressl360))]
pub const EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND: c_int = 0;
#[cfg(any(ossl111, libressl360))]
pub const EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY: c_int = 1;
#[cfg(any(ossl111, libressl360))]
pub const EVP_PKEY_HKDEF_MODE_EXPAND_ONLY: c_int = 2;
#[cfg(any(ossl110, libressl360))]
pub const EVP_PKEY_CTRL_HKDF_MD: c_int = EVP_PKEY_ALG_CTRL + 3;
#[cfg(any(ossl110, libressl360))]
pub const EVP_PKEY_CTRL_HKDF_SALT: c_int = EVP_PKEY_ALG_CTRL + 4;
#[cfg(any(ossl110, libressl360))]
pub const EVP_PKEY_CTRL_HKDF_KEY: c_int = EVP_PKEY_ALG_CTRL + 5;
#[cfg(any(ossl110, libressl360))]
pub const EVP_PKEY_CTRL_HKDF_INFO: c_int = EVP_PKEY_ALG_CTRL + 6;
#[cfg(any(ossl111, libressl360))]
pub const EVP_PKEY_CTRL_HKDF_MODE: c_int = EVP_PKEY_ALG_CTRL + 7;
#[cfg(any(all(ossl111, not(ossl300)), libressl360))]
pub unsafe fn EVP_PKEY_CTX_set_hkdf_mode(ctx: *mut EVP_PKEY_CTX, mode: c_int) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
-1,
EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_HKDF_MODE,
mode,
std::ptr::null_mut(),
)
}
#[cfg(any(all(ossl110, not(ossl300)), libressl360))]
pub unsafe fn EVP_PKEY_CTX_set_hkdf_md(ctx: *mut EVP_PKEY_CTX, md: *const EVP_MD) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
-1,
EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_HKDF_MD,
0,
md as *mut c_void,
)
}
#[cfg(any(all(ossl110, not(ossl300)), libressl360))]
pub unsafe fn EVP_PKEY_CTX_set1_hkdf_salt(
ctx: *mut EVP_PKEY_CTX,
salt: *const u8,
saltlen: c_int,
) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
-1,
EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_HKDF_SALT,
saltlen,
salt as *mut c_void,
)
}
#[cfg(any(all(ossl110, not(ossl300)), libressl360))]
pub unsafe fn EVP_PKEY_CTX_set1_hkdf_key(
ctx: *mut EVP_PKEY_CTX,
key: *const u8,
keylen: c_int,
) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
-1,
EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_HKDF_KEY,
keylen,
key as *mut c_void,
)
}
#[cfg(any(all(ossl110, not(ossl300)), libressl360))]
pub unsafe fn EVP_PKEY_CTX_add1_hkdf_info(
ctx: *mut EVP_PKEY_CTX,
info: *const u8,
infolen: c_int,
) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
-1,
EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_HKDF_INFO,
infolen,
info as *mut c_void,
)
}
#[cfg(not(any(ossl300, boringssl, awslc)))]
pub unsafe fn EVP_PKEY_CTX_set_signature_md(cxt: *mut EVP_PKEY_CTX, md: *mut EVP_MD) -> c_int {
EVP_PKEY_CTX_ctrl(
cxt,
-1,
EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_MD,
0,
md as *mut c_void,
)
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
pub unsafe fn EVP_PKEY_assign_RSA(pkey: *mut EVP_PKEY, rsa: *mut RSA) -> c_int {
EVP_PKEY_assign(pkey, EVP_PKEY_RSA, rsa as *mut c_void)
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
pub unsafe fn EVP_PKEY_assign_DSA(pkey: *mut EVP_PKEY, dsa: *mut DSA) -> c_int {
EVP_PKEY_assign(pkey, EVP_PKEY_DSA, dsa as *mut c_void)
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
pub unsafe fn EVP_PKEY_assign_DH(pkey: *mut EVP_PKEY, dh: *mut DH) -> c_int {
EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh as *mut c_void)
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
pub unsafe fn EVP_PKEY_assign_EC_KEY(pkey: *mut EVP_PKEY, ec_key: *mut EC_KEY) -> c_int {
EVP_PKEY_assign(pkey, EVP_PKEY_EC, ec_key as *mut c_void)
}

View File

@@ -0,0 +1,42 @@
use super::super::*;
use cratecrate::cratecrate::crate::libc::*;
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
#[repr(C)]
pub struct AES_KEY {
// There is some business with AES_LONG which is there to ensure the values here are 32 bits
rd_key: [u32; 4 * (AES_MAXNR as usize + 1)],
rounds: c_int,
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
extern "C" {
pub fn AES_set_encrypt_key(userKey: *const c_uchar, bits: c_int, key: *mut AES_KEY) -> c_int;
pub fn AES_set_decrypt_key(userKey: *const c_uchar, bits: c_int, key: *mut AES_KEY) -> c_int;
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
pub fn AES_ige_encrypt(
in_: *const c_uchar,
out: *mut c_uchar,
length: size_t,
key: *const AES_KEY,
ivec: *mut c_uchar,
enc: c_int,
);
pub fn AES_wrap_key(
key: *mut AES_KEY,
iv: *const c_uchar,
out: *mut c_uchar,
in_: *const c_uchar,
inlen: c_uint,
) -> c_int;
pub fn AES_unwrap_key(
key: *mut AES_KEY,
iv: *const c_uchar,
out: *mut c_uchar,
in_: *const c_uchar,
inlen: c_uint,
) -> c_int;
}

View File

@@ -0,0 +1,119 @@
use super::super::*;
use cratecrate::cratecrate::crate::libc::*;
#[repr(C)]
pub struct ASN1_ENCODING {
pub enc: *mut c_uchar,
pub len: c_long,
pub modified: c_int,
}
extern "C" {
pub fn ASN1_OBJECT_free(x: *mut ASN1_OBJECT);
pub fn OBJ_dup(x: *const ASN1_OBJECT) -> *mut ASN1_OBJECT;
}
stack!(stack_st_ASN1_OBJECT);
#[repr(C)]
pub struct ASN1_TYPE {
pub type_: c_int,
pub value: ASN1_TYPE_value,
}
#[repr(C)]
pub union ASN1_TYPE_value {
pub ptr: *mut c_char,
pub boolean: ASN1_BOOLEAN,
pub asn1_string: *mut ASN1_STRING,
pub object: *mut ASN1_OBJECT,
pub integer: *mut ASN1_INTEGER,
pub enumerated: *mut ASN1_ENUMERATED,
pub bit_string: *mut ASN1_BIT_STRING,
pub octet_string: *mut ASN1_OCTET_STRING,
pub printablestring: *mut ASN1_PRINTABLESTRING,
pub t61string: *mut ASN1_T61STRING,
pub ia5string: *mut ASN1_IA5STRING,
pub generalstring: *mut ASN1_GENERALSTRING,
pub bmpstring: *mut ASN1_BMPSTRING,
pub universalstring: *mut ASN1_UNIVERSALSTRING,
pub utctime: *mut ASN1_UTCTIME,
pub generalizedtime: *mut ASN1_GENERALIZEDTIME,
pub visiblestring: *mut ASN1_VISIBLESTRING,
pub utf8string: *mut ASN1_UTF8STRING,
pub set: *mut ASN1_STRING,
pub sequence: *mut ASN1_STRING,
pub asn1_value: *mut ASN1_VALUE,
}
extern "C" {
pub fn ASN1_STRING_type_new(ty: c_int) -> *mut ASN1_STRING;
#[cfg(any(ossl110, libressl))]
pub fn ASN1_STRING_get0_data(x: *const ASN1_STRING) -> *const c_uchar;
#[cfg(any(all(ossl102, not(ossl110)), libressl))]
pub fn ASN1_STRING_data(x: *mut ASN1_STRING) -> *mut c_uchar;
pub fn ASN1_STRING_new() -> *mut ASN1_STRING;
pub fn ASN1_OCTET_STRING_new() -> *mut ASN1_OCTET_STRING;
pub fn ASN1_STRING_free(x: *mut ASN1_STRING);
pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> c_int;
pub fn ASN1_STRING_set(x: *mut ASN1_STRING, data: *const c_void, len_in: c_int) -> c_int;
pub fn ASN1_OCTET_STRING_set(
x: *mut ASN1_OCTET_STRING,
data: *const c_uchar,
len_in: c_int,
) -> c_int;
pub fn ASN1_BIT_STRING_free(x: *mut ASN1_BIT_STRING);
pub fn ASN1_OCTET_STRING_free(x: *mut ASN1_OCTET_STRING);
pub fn ASN1_GENERALIZEDTIME_new() -> *mut ASN1_GENERALIZEDTIME;
pub fn ASN1_GENERALIZEDTIME_free(tm: *mut ASN1_GENERALIZEDTIME);
pub fn ASN1_GENERALIZEDTIME_print(b: *mut BIO, tm: *const ASN1_GENERALIZEDTIME) -> c_int;
pub fn ASN1_GENERALIZEDTIME_set_string(
s: *mut ASN1_GENERALIZEDTIME,
str: *const c_char,
) -> c_int;
pub fn ASN1_TIME_new() -> *mut ASN1_TIME;
pub fn ASN1_TIME_diff(
pday: *mut c_int,
psec: *mut c_int,
from: *const ASN1_TIME,
to: *const ASN1_TIME,
) -> c_int;
pub fn ASN1_TIME_free(tm: *mut ASN1_TIME);
pub fn ASN1_TIME_print(b: *mut BIO, tm: *const ASN1_TIME) -> c_int;
pub fn ASN1_TIME_set(from: *mut ASN1_TIME, to: time_t) -> *mut ASN1_TIME;
pub fn ASN1_INTEGER_free(x: *mut ASN1_INTEGER);
pub fn ASN1_INTEGER_dup(a: *const ASN1_INTEGER) -> *mut ASN1_INTEGER;
pub fn ASN1_INTEGER_get(dest: *const ASN1_INTEGER) -> c_long;
pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int;
pub fn ASN1_INTEGER_cmp(a: *const ASN1_INTEGER, b: *const ASN1_INTEGER) -> c_int;
pub fn BN_to_ASN1_INTEGER(bn: *const BIGNUM, ai: *mut ASN1_INTEGER) -> *mut ASN1_INTEGER;
pub fn ASN1_INTEGER_to_BN(ai: *const ASN1_INTEGER, bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn ASN1_TIME_set_string(s: *mut ASN1_TIME, str: *const c_char) -> c_int;
#[cfg(ossl111)]
pub fn ASN1_TIME_set_string_X509(s: *mut ASN1_TIME, str: *const c_char) -> c_int;
pub fn ASN1_ENUMERATED_free(a: *mut ASN1_ENUMERATED);
#[cfg(ossl110)]
pub fn ASN1_ENUMERATED_get_int64(pr: *mut i64, a: *const ASN1_ENUMERATED) -> c_int;
pub fn ASN1_TYPE_new() -> *mut ASN1_TYPE;
pub fn ASN1_TYPE_set(a: *mut ASN1_TYPE, type_: c_int, value: *mut c_void);
pub fn ASN1_TYPE_free(x: *mut ASN1_TYPE);
pub fn d2i_ASN1_TYPE(
k: *mut *mut ASN1_TYPE,
buf: *mut *const u8,
len: c_long,
) -> *mut ASN1_TYPE;
}
const_ptr_api! {
extern "C" {
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: #[const_ptr_if(any(ossl110, libressl))] ASN1_STRING) -> c_int;
pub fn ASN1_STRING_type(x: #[const_ptr_if(any(ossl110, libressl))] ASN1_STRING) -> c_int;
pub fn ASN1_generate_v3(str: #[const_ptr_if(any(ossl110, libressl))] c_char, cnf: *mut X509V3_CTX) -> *mut ASN1_TYPE;
pub fn i2d_ASN1_TYPE(a: #[const_ptr_if(ossl300)] ASN1_TYPE, pp: *mut *mut c_uchar) -> c_int;
}
}

View File

@@ -0,0 +1,165 @@
use super::super::*;
use cratecrate::cratecrate::crate::libc::*;
extern "C" {
pub fn BIO_set_flags(b: *mut BIO, flags: c_int);
pub fn BIO_clear_flags(b: *mut BIO, flags: c_int);
}
pub type bio_info_cb =
Option<unsafe extern "C" fn(*mut BIO, c_int, *const c_char, c_int, c_long, c_long)>;
cfg_if! {
if #[cfg(any(ossl110, libressl))] {
pub enum BIO_METHOD {}
} else {
#[repr(C)]
pub struct BIO_METHOD {
pub type_: c_int,
pub name: *const c_char,
pub bwrite: Option<unsafe extern "C" fn(*mut BIO, *const c_char, c_int) -> c_int>,
pub bread: Option<unsafe extern "C" fn(*mut BIO, *mut c_char, c_int) -> c_int>,
pub bputs: Option<unsafe extern "C" fn(*mut BIO, *const c_char) -> c_int>,
pub bgets: Option<unsafe extern "C" fn(*mut BIO, *mut c_char, c_int) -> c_int>,
pub ctrl: Option<unsafe extern "C" fn(*mut BIO, c_int, c_long, *mut c_void) -> c_long>,
pub create: Option<unsafe extern "C" fn(*mut BIO) -> c_int>,
pub destroy: Option<unsafe extern "C" fn(*mut BIO) -> c_int>,
pub callback_ctrl: Option<unsafe extern "C" fn(*mut BIO, c_int, bio_info_cb) -> c_long>,
}
}
}
const_ptr_api! {
extern "C" {
pub fn BIO_s_file() -> #[const_ptr_if(any(ossl110, libressl))] BIO_METHOD;
pub fn BIO_new(type_: #[const_ptr_if(any(ossl110, libressl))] BIO_METHOD) -> *mut BIO;
}
}
extern "C" {
#[cfg(not(osslconf = "OPENSSL_NO_STDIO"))]
pub fn BIO_new_fp(stream: *mut FILE, close_flag: c_int) -> *mut BIO;
#[cfg(any(ossl110, libressl))]
pub fn BIO_set_data(a: *mut BIO, data: *mut c_void);
#[cfg(any(ossl110, libressl))]
pub fn BIO_get_data(a: *mut BIO) -> *mut c_void;
#[cfg(any(ossl110, libressl))]
pub fn BIO_set_init(a: *mut BIO, init: c_int);
pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int;
pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int;
pub fn BIO_ctrl(b: *mut BIO, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long;
pub fn BIO_free_all(b: *mut BIO);
pub fn BIO_new_mem_buf(buf: *const c_void, len: c_int) -> *mut BIO;
}
const_ptr_api! {
extern "C" {
pub fn BIO_s_mem() -> #[const_ptr_if(any(ossl110, libressl))] BIO_METHOD;
}
}
extern "C" {
#[cfg(not(osslconf = "OPENSSL_NO_SOCK"))]
pub fn BIO_new_socket(sock: c_int, close_flag: c_int) -> *mut BIO;
#[cfg(any(ossl110, libressl))]
pub fn BIO_meth_new(type_: c_int, name: *const c_char) -> *mut BIO_METHOD;
#[cfg(any(ossl110, libressl))]
pub fn BIO_meth_free(biom: *mut BIO_METHOD);
}
#[allow(clashing_extern_declarations)]
extern "C" {
#[cfg(any(ossl110, libressl))]
#[link_name = "BIO_meth_set_write"]
pub fn BIO_meth_set_write__fixed_rust(
biom: *mut BIO_METHOD,
write: Option<unsafe extern "C" fn(*mut BIO, *const c_char, c_int) -> c_int>,
) -> c_int;
#[cfg(any(ossl110, libressl))]
#[link_name = "BIO_meth_set_read"]
pub fn BIO_meth_set_read__fixed_rust(
biom: *mut BIO_METHOD,
read: Option<unsafe extern "C" fn(*mut BIO, *mut c_char, c_int) -> c_int>,
) -> c_int;
#[cfg(any(ossl110, libressl))]
#[link_name = "BIO_meth_set_puts"]
pub fn BIO_meth_set_puts__fixed_rust(
biom: *mut BIO_METHOD,
read: Option<unsafe extern "C" fn(*mut BIO, *const c_char) -> c_int>,
) -> c_int;
#[cfg(any(ossl110, libressl))]
#[link_name = "BIO_meth_set_ctrl"]
pub fn BIO_meth_set_ctrl__fixed_rust(
biom: *mut BIO_METHOD,
read: Option<unsafe extern "C" fn(*mut BIO, c_int, c_long, *mut c_void) -> c_long>,
) -> c_int;
#[cfg(any(ossl110, libressl))]
#[link_name = "BIO_meth_set_create"]
pub fn BIO_meth_set_create__fixed_rust(
biom: *mut BIO_METHOD,
create: Option<unsafe extern "C" fn(*mut BIO) -> c_int>,
) -> c_int;
#[cfg(any(ossl110, libressl))]
#[link_name = "BIO_meth_set_destroy"]
pub fn BIO_meth_set_destroy__fixed_rust(
biom: *mut BIO_METHOD,
destroy: Option<unsafe extern "C" fn(*mut BIO) -> c_int>,
) -> c_int;
}
#[cfg(ossl320)]
extern "C" {
pub fn BIO_meth_set_sendmmsg(
biom: *mut BIO_METHOD,
f: Option<
unsafe extern "C" fn(
arg1: *mut BIO,
arg2: *mut BIO_MSG,
arg3: usize,
arg4: usize,
arg5: u64,
arg6: *mut usize,
) -> c_int,
>,
) -> c_int;
pub fn BIO_meth_set_recvmmsg(
biom: *mut BIO_METHOD,
f: Option<
unsafe extern "C" fn(
arg1: *mut BIO,
arg2: *mut BIO_MSG,
arg3: usize,
arg4: usize,
arg5: u64,
arg6: *mut usize,
) -> c_int,
>,
) -> c_int;
pub fn BIO_new_bio_dgram_pair(
bio1: *mut *mut BIO,
writebuf1: usize,
bio2: *mut *mut BIO,
writebuf2: usize,
) -> c_int;
pub fn BIO_s_dgram_pair() -> *const BIO_METHOD;
pub fn BIO_s_datagram() -> *const BIO_METHOD;
pub fn BIO_get_rpoll_descriptor(b: *mut BIO, desc: *mut BIO_POLL_DESCRIPTOR) -> c_int;
pub fn BIO_get_wpoll_descriptor(b: *mut BIO, desc: *mut BIO_POLL_DESCRIPTOR) -> c_int;
pub fn BIO_sendmmsg(
b: *mut BIO,
msg: *mut BIO_MSG,
stride: usize,
num_msg: usize,
flags: u64,
msgs_processed: *mut usize,
) -> c_int;
pub fn BIO_recvmmsg(
b: *mut BIO,
msg: *mut BIO_MSG,
stride: usize,
num_msg: usize,
flags: u64,
msgs_processed: *mut usize,
) -> c_int;
pub fn BIO_err_is_non_fatal(errcode: c_uint) -> c_int;
}

View File

@@ -0,0 +1,176 @@
use super::super::*;
use cratecrate::cratecrate::crate::libc::*;
extern "C" {
pub fn BN_CTX_new() -> *mut BN_CTX;
#[cfg(ossl110)]
pub fn BN_CTX_secure_new() -> *mut BN_CTX;
pub fn BN_CTX_free(ctx: *mut BN_CTX);
pub fn BN_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int;
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
pub fn BN_pseudo_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int;
pub fn BN_rand_range(r: *mut BIGNUM, range: *const BIGNUM) -> c_int;
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
pub fn BN_pseudo_rand_range(r: *mut BIGNUM, range: *const BIGNUM) -> c_int;
pub fn BN_new() -> *mut BIGNUM;
#[cfg(ossl110)]
pub fn BN_secure_new() -> *mut BIGNUM;
#[cfg(ossl110)]
pub fn BN_set_flags(b: *mut BIGNUM, n: c_int);
#[cfg(ossl110)]
pub fn BN_get_flags(b: *const BIGNUM, n: c_int) -> c_int;
pub fn BN_num_bits(bn: *const BIGNUM) -> c_int;
pub fn BN_clear_free(bn: *mut BIGNUM);
pub fn BN_bin2bn(s: *const u8, size: c_int, ret: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_bn2bin(a: *const BIGNUM, to: *mut u8) -> c_int;
#[cfg(any(ossl110, libressl))]
pub fn BN_bn2binpad(a: *const BIGNUM, to: *mut u8, tolen: c_int) -> c_int;
pub fn BN_sub(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int;
pub fn BN_add(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int;
pub fn BN_mul(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
pub fn BN_sqr(r: *mut BIGNUM, a: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
pub fn BN_set_negative(bn: *mut BIGNUM, n: c_int);
#[cfg(any(ossl110, libressl))]
pub fn BN_is_negative(b: *const BIGNUM) -> c_int;
#[cfg(any(ossl110, libressl))]
pub fn BN_is_odd(b: *const BIGNUM) -> c_int;
pub fn BN_div(
dv: *mut BIGNUM,
rem: *mut BIGNUM,
a: *const BIGNUM,
b: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_nnmod(
rem: *mut BIGNUM,
a: *const BIGNUM,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_mod_add(
r: *mut BIGNUM,
a: *const BIGNUM,
b: *const BIGNUM,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_mod_sub(
r: *mut BIGNUM,
a: *const BIGNUM,
b: *const BIGNUM,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_mod_mul(
r: *mut BIGNUM,
a: *const BIGNUM,
b: *const BIGNUM,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_mod_sqr(
r: *mut BIGNUM,
a: *const BIGNUM,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_mod_sqrt(
ret: *mut BIGNUM,
a: *const BIGNUM,
p: *const BIGNUM,
ctx: *mut BN_CTX,
) -> *mut BIGNUM;
pub fn BN_mod_word(r: *const BIGNUM, w: BN_ULONG) -> BN_ULONG;
pub fn BN_div_word(r: *mut BIGNUM, w: BN_ULONG) -> BN_ULONG;
pub fn BN_mul_word(r: *mut BIGNUM, w: BN_ULONG) -> c_int;
pub fn BN_add_word(r: *mut BIGNUM, w: BN_ULONG) -> c_int;
pub fn BN_sub_word(r: *mut BIGNUM, w: BN_ULONG) -> c_int;
pub fn BN_set_word(bn: *mut BIGNUM, n: BN_ULONG) -> c_int;
pub fn BN_cmp(a: *const BIGNUM, b: *const BIGNUM) -> c_int;
pub fn BN_free(bn: *mut BIGNUM);
pub fn BN_is_bit_set(a: *const BIGNUM, n: c_int) -> c_int;
pub fn BN_lshift(r: *mut BIGNUM, a: *const BIGNUM, n: c_int) -> c_int;
pub fn BN_lshift1(r: *mut BIGNUM, a: *const BIGNUM) -> c_int;
pub fn BN_exp(r: *mut BIGNUM, a: *const BIGNUM, p: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
pub fn BN_mod_exp(
r: *mut BIGNUM,
a: *const BIGNUM,
p: *const BIGNUM,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_mask_bits(a: *mut BIGNUM, n: c_int) -> c_int;
pub fn BN_rshift(r: *mut BIGNUM, a: *const BIGNUM, n: c_int) -> c_int;
pub fn BN_rshift1(r: *mut BIGNUM, a: *const BIGNUM) -> c_int;
pub fn BN_bn2hex(a: *const BIGNUM) -> *mut c_char;
pub fn BN_bn2dec(a: *const BIGNUM) -> *mut c_char;
pub fn BN_hex2bn(a: *mut *mut BIGNUM, s: *const c_char) -> c_int;
pub fn BN_dec2bn(a: *mut *mut BIGNUM, s: *const c_char) -> c_int;
pub fn BN_gcd(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
pub fn BN_mod_inverse(
r: *mut BIGNUM,
a: *const BIGNUM,
n: *const BIGNUM,
ctx: *mut BN_CTX,
) -> *mut BIGNUM;
pub fn BN_clear(bn: *mut BIGNUM);
pub fn BN_dup(n: *const BIGNUM) -> *mut BIGNUM;
pub fn BN_ucmp(a: *const BIGNUM, b: *const BIGNUM) -> c_int;
pub fn BN_set_bit(a: *mut BIGNUM, n: c_int) -> c_int;
pub fn BN_clear_bit(a: *mut BIGNUM, n: c_int) -> c_int;
pub fn BN_generate_prime_ex(
r: *mut BIGNUM,
bits: c_int,
safe: c_int,
add: *const BIGNUM,
rem: *const BIGNUM,
cb: *mut BN_GENCB,
) -> c_int;
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
pub fn BN_is_prime_ex(
p: *const BIGNUM,
checks: c_int,
ctx: *mut BN_CTX,
cb: *mut BN_GENCB,
) -> c_int;
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
pub fn BN_is_prime_fasttest_ex(
p: *const BIGNUM,
checks: c_int,
ctx: *mut BN_CTX,
do_trial_division: c_int,
cb: *mut BN_GENCB,
) -> c_int;
}
cfg_if! {
if #[cfg(any(ossl110, libressl))] {
extern "C" {
pub fn BN_get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM;
}
} else {
extern "C" {
pub fn get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM;
}
}
}

View File

@@ -0,0 +1,19 @@
use cratecrate::cratecrate::crate::libc::*;
use super::super::*;
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
extern "C" {
pub fn CMAC_CTX_new() -> *mut CMAC_CTX;
pub fn CMAC_CTX_free(ctx: *mut CMAC_CTX);
pub fn CMAC_Init(
ctx: *mut CMAC_CTX,
key: *const c_void,
len: size_t,
cipher: *const EVP_CIPHER,
impl_: *mut ENGINE,
) -> c_int;
pub fn CMAC_Update(ctx: *mut CMAC_CTX, data: *const c_void, len: size_t) -> c_int;
pub fn CMAC_Final(ctx: *mut CMAC_CTX, out: *mut c_uchar, len: *mut size_t) -> c_int;
pub fn CMAC_CTX_copy(dst: *mut CMAC_CTX, src: *const CMAC_CTX) -> c_int;
}

View File

@@ -0,0 +1,57 @@
use super::super::*;
use cratecrate::cratecrate::crate::libc::*;
pub enum CMS_ContentInfo {}
extern "C" {
pub fn CMS_ContentInfo_free(cms: *mut CMS_ContentInfo);
}
const_ptr_api! {
extern "C" {
pub fn i2d_CMS_ContentInfo(a: #[const_ptr_if(ossl300)] CMS_ContentInfo, pp: *mut *mut c_uchar) -> c_int;
}
}
extern "C" {
pub fn d2i_CMS_ContentInfo(
a: *mut *mut CMS_ContentInfo,
pp: *mut *const c_uchar,
length: c_long,
) -> *mut CMS_ContentInfo;
pub fn SMIME_read_CMS(bio: *mut BIO, bcont: *mut *mut BIO) -> *mut CMS_ContentInfo;
pub fn CMS_sign(
signcert: *mut X509,
pkey: *mut EVP_PKEY,
certs: *mut stack_st_X509,
data: *mut BIO,
flags: c_uint,
) -> *mut CMS_ContentInfo;
pub fn CMS_verify(
cms: *mut CMS_ContentInfo,
certs: *mut stack_st_X509,
store: *mut X509_STORE,
detached_data: *mut BIO,
out: *mut BIO,
flags: c_uint,
) -> c_int;
pub fn CMS_encrypt(
certs: *mut stack_st_X509,
data: *mut BIO,
cipher: *const EVP_CIPHER,
flags: c_uint,
) -> *mut CMS_ContentInfo;
pub fn CMS_decrypt(
cms: *mut CMS_ContentInfo,
pkey: *mut EVP_PKEY,
cert: *mut X509,
dcont: *mut BIO,
out: *mut BIO,
flags: c_uint,
) -> c_int;
}

View File

@@ -0,0 +1,13 @@
use super::super::*;
const_ptr_api! {
extern "C" {
pub fn NCONF_new(meth: #[const_ptr_if(libressl400)] CONF_METHOD) -> *mut CONF;
}
}
extern "C" {
#[cfg(not(libressl400))]
pub fn NCONF_default() -> *mut CONF_METHOD;
pub fn NCONF_free(conf: *mut CONF);
}

View File

@@ -0,0 +1,85 @@
use super::super::*;
use cratecrate::cratecrate::crate::libc::*;
stack!(stack_st_void);
cfg_if! {
if #[cfg(any(ossl110, libressl))] {
extern "C" {
pub fn OpenSSL_version_num() -> c_ulong;
pub fn OpenSSL_version(key: c_int) -> *const c_char;
}
} else {
extern "C" {
pub fn SSLeay() -> c_ulong;
pub fn SSLeay_version(key: c_int) -> *const c_char;
}
}
}
extern "C" {
#[cfg(any(ossl110, libressl))]
pub fn CRYPTO_get_ex_new_index(
class_index: c_int,
argl: c_long,
argp: *mut c_void,
new_func: Option<CRYPTO_EX_new>,
dup_func: Option<CRYPTO_EX_dup>,
free_func: Option<CRYPTO_EX_free>,
) -> c_int;
#[cfg(not(ossl110))]
pub fn CRYPTO_num_locks() -> c_int;
}
#[allow(clashing_extern_declarations)]
extern "C" {
#[cfg(not(ossl110))]
#[link_name = "CRYPTO_set_locking_callback"]
pub fn CRYPTO_set_locking_callback__fixed_rust(
func: Option<unsafe extern "C" fn(mode: c_int, n: c_int, file: *const c_char, line: c_int)>,
);
#[cfg(not(ossl110))]
#[link_name = "CRYPTO_set_id_callback"]
pub fn CRYPTO_set_id_callback__fixed_rust(func: Option<unsafe extern "C" fn() -> c_ulong>);
}
extern "C" {
#[cfg(not(ossl110))]
pub fn CRYPTO_add_lock(
pointer: *mut c_int,
amount: c_int,
type_: c_int,
file: *const c_char,
line: c_int,
) -> c_int;
}
cfg_if! {
if #[cfg(any(ossl110, libressl390))] {
extern "C" {
pub fn CRYPTO_malloc(num: size_t, file: *const c_char, line: c_int) -> *mut c_void;
pub fn CRYPTO_free(buf: *mut c_void, file: *const c_char, line: c_int);
}
} else {
extern "C" {
pub fn CRYPTO_malloc(num: c_int, file: *const c_char, line: c_int) -> *mut c_void;
pub fn CRYPTO_free(buf: *mut c_void);
}
}
}
extern "C" {
#[cfg(all(ossl102, not(ossl300)))]
pub fn FIPS_mode() -> c_int;
#[cfg(all(ossl102, not(ossl300)))]
pub fn FIPS_mode_set(onoff: c_int) -> c_int;
pub fn CRYPTO_memcmp(a: *const c_void, b: *const c_void, len: size_t) -> c_int;
#[cfg(ossl300)]
pub fn OSSL_LIB_CTX_new() -> *mut OSSL_LIB_CTX;
#[cfg(ossl300)]
pub fn OSSL_LIB_CTX_free(libcts: *mut OSSL_LIB_CTX);
}

View File

@@ -0,0 +1,52 @@
use super::super::*;
use cratecrate::cratecrate::crate::libc::*;
extern "C" {
pub fn OSSL_DECODER_CTX_new() -> *mut OSSL_DECODER_CTX;
pub fn OSSL_DECODER_CTX_free(ctx: *mut OSSL_DECODER_CTX);
pub fn OSSL_DECODER_CTX_new_for_pkey(
pkey: *mut *mut EVP_PKEY,
input_type: *const c_char,
input_struct: *const c_char,
keytype: *const c_char,
selection: c_int,
libctx: *mut OSSL_LIB_CTX,
propquery: *const c_char,
) -> *mut OSSL_DECODER_CTX;
pub fn OSSL_DECODER_CTX_set_selection(ctx: *mut OSSL_DECODER_CTX, selection: c_int) -> c_int;
pub fn OSSL_DECODER_CTX_set_input_type(
ctx: *mut OSSL_DECODER_CTX,
input_type: *const c_char,
) -> c_int;
pub fn OSSL_DECODER_CTX_set_input_structure(
ctx: *mut OSSL_DECODER_CTX,
input_structure: *const c_char,
) -> c_int;
pub fn OSSL_DECODER_CTX_set_passphrase(
ctx: *mut OSSL_DECODER_CTX,
kstr: *const c_uchar,
klen: size_t,
) -> c_int;
pub fn OSSL_DECODER_CTX_set_pem_password_cb(
ctx: *mut OSSL_DECODER_CTX,
cb: pem_password_cb,
cbarg: *mut c_void,
) -> c_int;
pub fn OSSL_DECODER_CTX_set_passphrase_cb(
ctx: *mut OSSL_DECODER_CTX,
cb: OSSL_PASSPHRASE_CALLBACK,
cbarg: *mut c_void,
) -> c_int;
pub fn OSSL_DECODER_from_bio(ctx: *mut OSSL_DECODER_CTX, b_in: *mut BIO) -> c_int;
#[cfg(not(osslconf = "OPENSSL_NO_STDIO"))]
pub fn OSSL_DECODER_from_fp(ctx: *mut OSSL_DECODER_CTX, fp: *mut FILE) -> c_int;
pub fn OSSL_DECODER_from_data(
ctx: *mut OSSL_DECODER_CTX,
pdata: *mut *const c_uchar,
pdata_len: *mut size_t,
) -> c_int;
}

View File

@@ -0,0 +1,59 @@
use super::super::*;
#[cfg(ossl300)]
extern "C" {
pub fn EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx: *mut EVP_PKEY_CTX, len: c_int) -> c_int;
pub fn EVP_PKEY_CTX_set_dh_paramgen_generator(ctx: *mut EVP_PKEY_CTX, gen: c_int) -> c_int;
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
extern "C" {
pub fn DH_new() -> *mut DH;
pub fn DH_free(dh: *mut DH);
pub fn DH_check(dh: *const DH, codes: *mut c_int) -> c_int;
#[cfg(not(libressl382))]
pub fn DH_generate_parameters(
prime_len: c_int,
generator: c_int,
callback: Option<extern "C" fn(c_int, c_int, *mut c_void)>,
cb_arg: *mut c_void,
) -> *mut DH;
pub fn DH_generate_parameters_ex(
dh: *mut DH,
prime_len: c_int,
generator: c_int,
cb: *mut BN_GENCB,
) -> c_int;
pub fn DH_generate_key(dh: *mut DH) -> c_int;
pub fn DH_compute_key(key: *mut c_uchar, pub_key: *const BIGNUM, dh: *mut DH) -> c_int;
pub fn DH_size(dh: *const DH) -> c_int;
pub fn d2i_DHparams(k: *mut *mut DH, pp: *mut *const c_uchar, length: c_long) -> *mut DH;
pub fn i2d_DHparams(dh: *const DH, pp: *mut *mut c_uchar) -> c_int;
#[cfg(ossl102)]
pub fn DH_get_1024_160() -> *mut DH;
#[cfg(ossl102)]
pub fn DH_get_2048_224() -> *mut DH;
#[cfg(ossl102)]
pub fn DH_get_2048_256() -> *mut DH;
#[cfg(any(ossl110, libressl))]
pub fn DH_set0_pqg(dh: *mut DH, p: *mut BIGNUM, q: *mut BIGNUM, g: *mut BIGNUM) -> c_int;
#[cfg(any(ossl110, libressl))]
pub fn DH_get0_pqg(
dh: *const DH,
p: *mut *const BIGNUM,
q: *mut *const BIGNUM,
g: *mut *const BIGNUM,
);
#[cfg(any(ossl110, libressl))]
pub fn DH_set0_key(dh: *mut DH, pub_key: *mut BIGNUM, priv_key: *mut BIGNUM) -> c_int;
#[cfg(any(ossl110, libressl))]
pub fn DH_get0_key(dh: *const DH, pub_key: *mut *const BIGNUM, priv_key: *mut *const BIGNUM);
}

View File

@@ -0,0 +1,94 @@
use cratecrate::cratecrate::crate::libc::*;
use super::super::*;
#[cfg(ossl300)]
extern "C" {
pub fn EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx: *mut EVP_PKEY_CTX, nbits: c_int) -> c_int;
}
cfg_if! {
if #[cfg(any(ossl110, libressl))] {
pub enum DSA_SIG {}
} else {
#[repr(C)]
pub struct DSA_SIG {
pub r: *mut BIGNUM,
pub s: *mut BIGNUM,
}
}
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
extern "C" {
pub fn DSA_new() -> *mut DSA;
pub fn DSA_free(dsa: *mut DSA);
pub fn DSA_up_ref(dsa: *mut DSA) -> c_int;
pub fn DSA_size(dsa: *const DSA) -> c_int;
pub fn DSA_sign(
dummy: c_int,
dgst: *const c_uchar,
len: c_int,
sigret: *mut c_uchar,
siglen: *mut c_uint,
dsa: *mut DSA,
) -> c_int;
pub fn DSA_verify(
dummy: c_int,
dgst: *const c_uchar,
len: c_int,
sigbuf: *const c_uchar,
siglen: c_int,
dsa: *mut DSA,
) -> c_int;
pub fn d2i_DSAPublicKey(a: *mut *mut DSA, pp: *mut *const c_uchar, length: c_long) -> *mut DSA;
pub fn d2i_DSAPrivateKey(a: *mut *mut DSA, pp: *mut *const c_uchar, length: c_long)
-> *mut DSA;
pub fn DSA_generate_parameters_ex(
dsa: *mut DSA,
bits: c_int,
seed: *const c_uchar,
seed_len: c_int,
counter_ref: *mut c_int,
h_ret: *mut c_ulong,
cb: *mut BN_GENCB,
) -> c_int;
pub fn DSA_generate_key(dsa: *mut DSA) -> c_int;
pub fn i2d_DSAPublicKey(a: *const DSA, pp: *mut *mut c_uchar) -> c_int;
pub fn i2d_DSAPrivateKey(a: *const DSA, pp: *mut *mut c_uchar) -> c_int;
#[cfg(any(ossl110, libressl))]
pub fn DSA_get0_pqg(
d: *const DSA,
p: *mut *const BIGNUM,
q: *mut *const BIGNUM,
q: *mut *const BIGNUM,
);
#[cfg(any(ossl110, libressl))]
pub fn DSA_set0_pqg(d: *mut DSA, p: *mut BIGNUM, q: *mut BIGNUM, q: *mut BIGNUM) -> c_int;
#[cfg(any(ossl110, libressl))]
pub fn DSA_get0_key(d: *const DSA, pub_key: *mut *const BIGNUM, priv_key: *mut *const BIGNUM);
#[cfg(any(ossl110, libressl))]
pub fn DSA_set0_key(d: *mut DSA, pub_key: *mut BIGNUM, priv_key: *mut BIGNUM) -> c_int;
}
extern "C" {
pub fn d2i_DSA_SIG(
sig: *mut *mut DSA_SIG,
pp: *mut *const c_uchar,
length: c_long,
) -> *mut DSA_SIG;
pub fn i2d_DSA_SIG(a: *const DSA_SIG, pp: *mut *mut c_uchar) -> c_int;
pub fn DSA_SIG_new() -> *mut DSA_SIG;
pub fn DSA_SIG_free(sig: *mut DSA_SIG);
#[cfg(any(ossl110, libressl))]
pub fn DSA_SIG_get0(sig: *const DSA_SIG, pr: *mut *const BIGNUM, ps: *mut *const BIGNUM);
#[cfg(any(ossl110, libressl))]
pub fn DSA_SIG_set0(sig: *mut DSA_SIG, pr: *mut BIGNUM, ps: *mut BIGNUM) -> c_int;
}

View File

@@ -0,0 +1,294 @@
use super::super::*;
use cratecrate::cratecrate::crate::libc::*;
#[cfg(ossl300)]
extern "C" {
pub fn EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx: *mut EVP_PKEY_CTX, nid: c_int) -> c_int;
}
#[repr(C)]
#[derive(Copy, Clone)]
pub enum point_conversion_form_t {
POINT_CONVERSION_COMPRESSED = 2,
POINT_CONVERSION_UNCOMPRESSED = 4,
POINT_CONVERSION_HYBRID = 6,
}
#[cfg(not(any(libressl410, osslconf = "OPENSSL_NO_DEPRECATED_3_0")))]
pub enum EC_METHOD {}
pub enum EC_GROUP {}
pub enum EC_POINT {}
extern "C" {
#[cfg(not(any(libressl410, osslconf = "OPENSSL_NO_DEPRECATED_3_0")))]
pub fn EC_GROUP_new(meth: *const EC_METHOD) -> *mut EC_GROUP;
pub fn EC_GROUP_dup(group: *const EC_GROUP) -> *mut EC_GROUP;
pub fn EC_GROUP_free(group: *mut EC_GROUP);
pub fn EC_GROUP_get_order(
group: *const EC_GROUP,
order: *mut BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_GROUP_get_cofactor(
group: *const EC_GROUP,
cofactor: *mut BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_GROUP_get0_generator(group: *const EC_GROUP) -> *const EC_POINT;
pub fn EC_GROUP_set_generator(
group: *mut EC_GROUP,
generator: *const EC_POINT,
order: *const BIGNUM,
cofactor: *const BIGNUM,
) -> c_int;
pub fn EC_GROUP_get_curve_name(group: *const EC_GROUP) -> c_int;
pub fn EC_GROUP_set_asn1_flag(key: *mut EC_GROUP, flag: c_int);
pub fn EC_GROUP_get_asn1_flag(group: *const EC_GROUP) -> c_int;
pub fn EC_GROUP_get_degree(group: *const EC_GROUP) -> c_int;
#[cfg(any(ossl110, libressl))]
pub fn EC_GROUP_order_bits(group: *const EC_GROUP) -> c_int;
pub fn EC_GROUP_new_curve_GFp(
p: *const BIGNUM,
a: *const BIGNUM,
b: *const BIGNUM,
ctx: *mut BN_CTX,
) -> *mut EC_GROUP;
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
pub fn EC_GROUP_new_curve_GF2m(
p: *const BIGNUM,
a: *const BIGNUM,
b: *const BIGNUM,
ctx: *mut BN_CTX,
) -> *mut EC_GROUP;
pub fn EC_GROUP_new_by_curve_name(nid: c_int) -> *mut EC_GROUP;
pub fn EC_POINT_is_at_infinity(group: *const EC_GROUP, point: *const EC_POINT) -> c_int;
pub fn EC_POINT_is_on_curve(
group: *const EC_GROUP,
point: *const EC_POINT,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_POINT_new(group: *const EC_GROUP) -> *mut EC_POINT;
pub fn EC_POINT_free(point: *mut EC_POINT);
pub fn EC_POINT_dup(p: *const EC_POINT, group: *const EC_GROUP) -> *mut EC_POINT;
#[cfg(any(ossl111, boringssl, libressl, awslc))]
pub fn EC_POINT_get_affine_coordinates(
group: *const EC_GROUP,
p: *const EC_POINT,
x: *mut BIGNUM,
y: *mut BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
#[cfg(any(ossl111, boringssl, libressl, awslc))]
pub fn EC_POINT_set_affine_coordinates(
group: *const EC_GROUP,
p: *mut EC_POINT,
x: *const BIGNUM,
y: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_POINT_point2oct(
group: *const EC_GROUP,
p: *const EC_POINT,
form: point_conversion_form_t,
buf: *mut c_uchar,
len: size_t,
ctx: *mut BN_CTX,
) -> size_t;
pub fn EC_POINT_oct2point(
group: *const EC_GROUP,
p: *mut EC_POINT,
buf: *const c_uchar,
len: size_t,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_POINT_point2hex(
group: *const EC_GROUP,
p: *const EC_POINT,
form: point_conversion_form_t,
ctx: *mut BN_CTX,
) -> *mut c_char;
pub fn EC_POINT_hex2point(
group: *const EC_GROUP,
s: *const c_char,
p: *mut EC_POINT,
ctx: *mut BN_CTX,
) -> *mut EC_POINT;
pub fn EC_POINT_add(
group: *const EC_GROUP,
r: *mut EC_POINT,
a: *const EC_POINT,
b: *const EC_POINT,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_POINT_invert(group: *const EC_GROUP, r: *mut EC_POINT, ctx: *mut BN_CTX) -> c_int;
pub fn EC_POINT_cmp(
group: *const EC_GROUP,
a: *const EC_POINT,
b: *const EC_POINT,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_POINT_mul(
group: *const EC_GROUP,
r: *mut EC_POINT,
n: *const BIGNUM,
q: *const EC_POINT,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
extern "C" {
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
pub fn EC_GF2m_simple_method() -> *const EC_METHOD;
pub fn EC_GROUP_get_curve_GFp(
group: *const EC_GROUP,
p: *mut BIGNUM,
a: *mut BIGNUM,
b: *mut BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
pub fn EC_GROUP_get_curve_GF2m(
group: *const EC_GROUP,
p: *mut BIGNUM,
a: *mut BIGNUM,
b: *mut BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_POINT_get_affine_coordinates_GFp(
group: *const EC_GROUP,
p: *const EC_POINT,
x: *mut BIGNUM,
y: *mut BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_POINT_set_affine_coordinates_GFp(
group: *const EC_GROUP,
p: *mut EC_POINT,
x: *const BIGNUM,
y: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
pub fn EC_POINT_get_affine_coordinates_GF2m(
group: *const EC_GROUP,
p: *const EC_POINT,
x: *mut BIGNUM,
y: *mut BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_KEY_new() -> *mut EC_KEY;
pub fn EC_KEY_new_by_curve_name(nid: c_int) -> *mut EC_KEY;
pub fn EC_KEY_free(key: *mut EC_KEY);
pub fn EC_KEY_dup(key: *const EC_KEY) -> *mut EC_KEY;
pub fn EC_KEY_up_ref(key: *mut EC_KEY) -> c_int;
pub fn EC_KEY_get0_group(key: *const EC_KEY) -> *const EC_GROUP;
pub fn EC_KEY_set_group(key: *mut EC_KEY, group: *const EC_GROUP) -> c_int;
pub fn EC_KEY_get0_private_key(key: *const EC_KEY) -> *const BIGNUM;
pub fn EC_KEY_set_private_key(key: *mut EC_KEY, key: *const BIGNUM) -> c_int;
pub fn EC_KEY_get0_public_key(key: *const EC_KEY) -> *const EC_POINT;
pub fn EC_KEY_set_public_key(key: *mut EC_KEY, key: *const EC_POINT) -> c_int;
pub fn EC_KEY_generate_key(key: *mut EC_KEY) -> c_int;
pub fn EC_KEY_check_key(key: *const EC_KEY) -> c_int;
pub fn EC_KEY_set_public_key_affine_coordinates(
key: *mut EC_KEY,
x: *mut BIGNUM,
y: *mut BIGNUM,
) -> c_int;
}
cfg_if! {
if #[cfg(any(ossl110, libressl))] {
pub enum ECDSA_SIG {}
} else {
#[repr(C)]
pub struct ECDSA_SIG {
pub r: *mut BIGNUM,
pub s: *mut BIGNUM,
}
}
}
extern "C" {
pub fn ECDSA_SIG_new() -> *mut ECDSA_SIG;
pub fn ECDSA_SIG_free(sig: *mut ECDSA_SIG);
#[cfg(any(ossl110, libressl))]
pub fn ECDSA_SIG_get0(sig: *const ECDSA_SIG, pr: *mut *const BIGNUM, ps: *mut *const BIGNUM);
#[cfg(any(ossl110, libressl))]
pub fn ECDSA_SIG_set0(sig: *mut ECDSA_SIG, pr: *mut BIGNUM, ps: *mut BIGNUM) -> c_int;
pub fn d2i_ECDSA_SIG(
sig: *mut *mut ECDSA_SIG,
inp: *mut *const c_uchar,
length: c_long,
) -> *mut ECDSA_SIG;
pub fn i2d_ECDSA_SIG(sig: *const ECDSA_SIG, out: *mut *mut c_uchar) -> c_int;
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
extern "C" {
pub fn ECDSA_do_sign(
dgst: *const c_uchar,
dgst_len: c_int,
eckey: *mut EC_KEY,
) -> *mut ECDSA_SIG;
pub fn ECDSA_do_verify(
dgst: *const c_uchar,
dgst_len: c_int,
sig: *const ECDSA_SIG,
eckey: *mut EC_KEY,
) -> c_int;
}

View File

@@ -0,0 +1,56 @@
use super::super::*;
use cratecrate::cratecrate::crate::libc::*;
#[cfg(ossl300)]
extern "C" {
pub fn OSSL_ENCODER_CTX_new() -> *mut OSSL_ENCODER_CTX;
pub fn OSSL_ENCODER_CTX_free(ctx: *mut OSSL_ENCODER_CTX);
pub fn OSSL_ENCODER_CTX_new_for_pkey(
pkey: *const EVP_PKEY,
selection: c_int,
output_type: *const c_char,
output_structure: *const c_char,
propquery: *const c_char,
) -> *mut OSSL_ENCODER_CTX;
pub fn OSSL_ENCODER_CTX_set_selection(ctx: *mut OSSL_ENCODER_CTX, selection: c_int) -> c_int;
pub fn OSSL_ENCODER_CTX_set_output_type(
ctx: *mut OSSL_ENCODER_CTX,
output_type: *const c_char,
) -> c_int;
pub fn OSSL_ENCODER_CTX_set_output_structure(
ctx: *mut OSSL_ENCODER_CTX,
output_structure: *const c_char,
) -> c_int;
pub fn OSSL_ENCODER_CTX_set_cipher(
ctx: *mut OSSL_ENCODER_CTX,
cipher_name: *const c_char,
propquery: *const c_char,
) -> c_int;
pub fn OSSL_ENCODER_CTX_set_passphrase(
ctx: *mut OSSL_ENCODER_CTX,
kstr: *const c_uchar,
klen: size_t,
) -> c_int;
pub fn OSSL_ENCODER_CTX_set_pem_password_cb(
ctx: *mut OSSL_ENCODER_CTX,
cb: pem_password_cb,
cbarg: *mut c_void,
) -> c_int;
pub fn OSSL_ENCODER_CTX_set_passphrase_cb(
ctx: *mut OSSL_ENCODER_CTX,
cb: OSSL_PASSPHRASE_CALLBACK,
cbarg: *mut c_void,
) -> c_int;
pub fn OSSL_ENCODER_to_data(
ctx: *mut OSSL_ENCODER_CTX,
pdata: *mut *mut c_uchar,
pdata_len: *mut size_t,
) -> c_int;
pub fn OSSL_ENCODER_to_bio(ctx: *mut OSSL_ENCODER_CTX, out: *mut BIO) -> c_int;
#[cfg(not(osslconf = "OPENSSL_NO_STDIO"))]
pub fn OSSL_ENCODER_to_fp(ctx: *mut OSSL_ENCODER_CTX, fp: *mut FILE) -> c_int;
}

View File

@@ -0,0 +1,59 @@
use super::super::*;
use cratecrate::cratecrate::crate::libc::*;
#[repr(C)]
pub struct ERR_STRING_DATA {
pub error: c_ulong,
pub string: *const c_char,
}
cfg_if! {
if #[cfg(ossl300)] {
extern "C" {
pub fn ERR_new();
pub fn ERR_set_debug(file: *const c_char, line: c_int, func: *const c_char);
pub fn ERR_set_error(lib: c_int, reason: c_int, fmt: *const c_char, ...);
}
} else {
extern "C" {
pub fn ERR_put_error(lib: c_int, func: c_int, reason: c_int, file: *const c_char, line: c_int);
}
}
}
extern "C" {
pub fn ERR_set_error_data(data: *mut c_char, flags: c_int);
pub fn ERR_get_error() -> c_ulong;
#[cfg(ossl300)]
pub fn ERR_get_error_all(
file: *mut *const c_char,
line: *mut c_int,
func: *mut *const c_char,
data: *mut *const c_char,
flags: *mut c_int,
) -> c_ulong;
pub fn ERR_peek_last_error() -> c_ulong;
pub fn ERR_clear_error();
pub fn ERR_lib_error_string(err: c_ulong) -> *const c_char;
pub fn ERR_reason_error_string(err: c_ulong) -> *const c_char;
#[cfg(ossl110)]
pub fn ERR_load_strings(lib: c_int, str: *mut ERR_STRING_DATA) -> c_int;
#[cfg(not(ossl110))]
pub fn ERR_load_strings(lib: c_int, str: *mut ERR_STRING_DATA);
#[cfg(not(ossl110))]
pub fn ERR_load_crypto_strings();
pub fn ERR_get_next_error_library() -> c_int;
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
extern "C" {
pub fn ERR_get_error_line_data(
file: *mut *const c_char,
line: *mut c_int,
data: *mut *const c_char,
flags: *mut c_int,
) -> c_ulong;
pub fn ERR_func_error_string(err: c_ulong) -> *const c_char;
}

View File

@@ -0,0 +1,860 @@
use super::super::*;
use cratecrate::cratecrate::crate::libc::*;
cfg_if! {
if #[cfg(ossl300)] {
extern "C" {
pub fn EVP_MD_get_block_size(md: *const EVP_MD) -> c_int;
pub fn EVP_MD_get_size(md: *const EVP_MD) -> c_int;
pub fn EVP_MD_get_type(md: *const EVP_MD) -> c_int;
pub fn EVP_MD_CTX_get0_md(ctx: *const EVP_MD_CTX) -> *const EVP_MD;
pub fn EVP_CIPHER_get_key_length(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_get_block_size(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_get_iv_length(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_get_nid(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_fetch(
ctx: *mut OSSL_LIB_CTX,
algorithm: *const c_char,
properties: *const c_char,
) -> *mut EVP_CIPHER;
pub fn EVP_CIPHER_free(cipher: *mut EVP_CIPHER);
pub fn EVP_CIPHER_CTX_get0_cipher(ctx: *const EVP_CIPHER_CTX) -> *const EVP_CIPHER;
pub fn EVP_CIPHER_CTX_get_block_size(ctx: *const EVP_CIPHER_CTX) -> c_int;
pub fn EVP_CIPHER_CTX_get_key_length(ctx: *const EVP_CIPHER_CTX) -> c_int;
pub fn EVP_CIPHER_CTX_get_iv_length(ctx: *const EVP_CIPHER_CTX) -> c_int;
pub fn EVP_CIPHER_CTX_get_tag_length(ctx: *const EVP_CIPHER_CTX) -> c_int;
pub fn EVP_CIPHER_CTX_get_num(ctx: *const EVP_CIPHER_CTX) -> c_int;
}
} else {
extern "C" {
pub fn EVP_MD_block_size(md: *const EVP_MD) -> c_int;
pub fn EVP_MD_size(md: *const EVP_MD) -> c_int;
pub fn EVP_MD_type(md: *const EVP_MD) -> c_int;
pub fn EVP_MD_CTX_md(ctx: *const EVP_MD_CTX) -> *const EVP_MD;
pub fn EVP_CIPHER_key_length(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_block_size(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_iv_length(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_nid(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_CTX_cipher(ctx: *const EVP_CIPHER_CTX) -> *const EVP_CIPHER;
pub fn EVP_CIPHER_CTX_block_size(ctx: *const EVP_CIPHER_CTX) -> c_int;
pub fn EVP_CIPHER_CTX_key_length(ctx: *const EVP_CIPHER_CTX) -> c_int;
pub fn EVP_CIPHER_CTX_iv_length(ctx: *const EVP_CIPHER_CTX) -> c_int;
#[cfg(ossl110)]
pub fn EVP_CIPHER_CTX_num(ctx: *const EVP_CIPHER_CTX) -> c_int;
}
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl382))] {
extern "C" {
pub fn EVP_MD_CTX_new() -> *mut EVP_MD_CTX;
pub fn EVP_MD_CTX_free(ctx: *mut EVP_MD_CTX);
}
} else {
extern "C" {
pub fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX;
pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
}
}
}
cfg_if! {
if #[cfg(ossl300)] {
extern "C" {
pub fn EVP_default_properties_is_fips_enabled(libctx: *mut OSSL_LIB_CTX) -> c_int;
pub fn EVP_default_properties_enable_fips(libctx: *mut OSSL_LIB_CTX, enable: c_int) -> c_int;
}
}
}
extern "C" {
pub fn EVP_DigestInit_ex(ctx: *mut EVP_MD_CTX, typ: *const EVP_MD, imple: *mut ENGINE)
-> c_int;
pub fn EVP_DigestUpdate(ctx: *mut EVP_MD_CTX, data: *const c_void, n: size_t) -> c_int;
pub fn EVP_DigestFinal_ex(ctx: *mut EVP_MD_CTX, res: *mut u8, n: *mut u32) -> c_int;
#[cfg(ossl300)]
pub fn EVP_Q_digest(
libctx: *mut OSSL_LIB_CTX,
name: *const c_char,
propq: *const c_char,
data: *const c_void,
count: size_t,
md: *mut c_uchar,
size: *mut size_t,
) -> c_int;
pub fn EVP_DigestInit(ctx: *mut EVP_MD_CTX, typ: *const EVP_MD) -> c_int;
pub fn EVP_DigestFinal(ctx: *mut EVP_MD_CTX, res: *mut u8, n: *mut u32) -> c_int;
#[cfg(ossl111)]
pub fn EVP_DigestFinalXOF(ctx: *mut EVP_MD_CTX, res: *mut u8, len: usize) -> c_int;
#[cfg(any(ossl330, awslc))]
pub fn EVP_DigestSqueeze(ctx: *mut EVP_MD_CTX, res: *mut u8, len: usize) -> c_int;
#[cfg(ossl300)]
pub fn EVP_MD_fetch(
ctx: *mut OSSL_LIB_CTX,
algorithm: *const c_char,
properties: *const c_char,
) -> *mut EVP_MD;
#[cfg(ossl300)]
pub fn EVP_MD_free(md: *mut EVP_MD);
pub fn EVP_BytesToKey(
typ: *const EVP_CIPHER,
md: *const EVP_MD,
salt: *const u8,
data: *const u8,
datalen: c_int,
count: c_int,
key: *mut u8,
iv: *mut u8,
) -> c_int;
pub fn EVP_CipherInit(
ctx: *mut EVP_CIPHER_CTX,
evp: *const EVP_CIPHER,
key: *const u8,
iv: *const u8,
mode: c_int,
) -> c_int;
pub fn EVP_CipherInit_ex(
ctx: *mut EVP_CIPHER_CTX,
type_: *const EVP_CIPHER,
impl_: *mut ENGINE,
key: *const c_uchar,
iv: *const c_uchar,
enc: c_int,
) -> c_int;
pub fn EVP_CipherUpdate(
ctx: *mut EVP_CIPHER_CTX,
outbuf: *mut u8,
outlen: *mut c_int,
inbuf: *const u8,
inlen: c_int,
) -> c_int;
pub fn EVP_CipherFinal(ctx: *mut EVP_CIPHER_CTX, res: *mut u8, len: *mut c_int) -> c_int;
pub fn EVP_DigestSignInit(
ctx: *mut EVP_MD_CTX,
pctx: *mut *mut EVP_PKEY_CTX,
type_: *const EVP_MD,
e: *mut ENGINE,
pkey: *mut EVP_PKEY,
) -> c_int;
#[cfg(ossl300)]
pub fn EVP_DigestSignUpdate(ctx: *mut EVP_MD_CTX, data: *const c_void, dsize: size_t) -> c_int;
pub fn EVP_DigestSignFinal(
ctx: *mut EVP_MD_CTX,
sig: *mut c_uchar,
siglen: *mut size_t,
) -> c_int;
pub fn EVP_DigestVerifyInit(
ctx: *mut EVP_MD_CTX,
pctx: *mut *mut EVP_PKEY_CTX,
type_: *const EVP_MD,
e: *mut ENGINE,
pkey: *mut EVP_PKEY,
) -> c_int;
#[cfg(ossl300)]
pub fn EVP_DigestVerifyUpdate(
ctx: *mut EVP_MD_CTX,
data: *const c_void,
dsize: size_t,
) -> c_int;
pub fn EVP_DigestVerifyFinal(
ctx: *mut EVP_MD_CTX,
sigret: *const c_uchar,
siglen: size_t,
) -> c_int;
pub fn EVP_SealInit(
ctx: *mut EVP_CIPHER_CTX,
type_: *const EVP_CIPHER,
ek: *mut *mut c_uchar,
ekl: *mut c_int,
iv: *mut c_uchar,
pubk: *mut *mut EVP_PKEY,
npubk: c_int,
) -> c_int;
pub fn EVP_SealFinal(ctx: *mut EVP_CIPHER_CTX, out: *mut c_uchar, outl: *mut c_int) -> c_int;
pub fn EVP_EncryptInit_ex(
ctx: *mut EVP_CIPHER_CTX,
cipher: *const EVP_CIPHER,
impl_: *mut ENGINE,
key: *const c_uchar,
iv: *const c_uchar,
) -> c_int;
pub fn EVP_EncryptUpdate(
ctx: *mut EVP_CIPHER_CTX,
out: *mut c_uchar,
outl: *mut c_int,
in_: *const u8,
inl: c_int,
) -> c_int;
pub fn EVP_EncryptFinal_ex(
ctx: *mut EVP_CIPHER_CTX,
out: *mut c_uchar,
outl: *mut c_int,
) -> c_int;
pub fn EVP_OpenInit(
ctx: *mut EVP_CIPHER_CTX,
type_: *const EVP_CIPHER,
ek: *const c_uchar,
ekl: c_int,
iv: *const c_uchar,
priv_: *mut EVP_PKEY,
) -> c_int;
pub fn EVP_OpenFinal(ctx: *mut EVP_CIPHER_CTX, out: *mut c_uchar, outl: *mut c_int) -> c_int;
pub fn EVP_DecryptInit_ex(
ctx: *mut EVP_CIPHER_CTX,
cipher: *const EVP_CIPHER,
impl_: *mut ENGINE,
key: *const c_uchar,
iv: *const c_uchar,
) -> c_int;
pub fn EVP_DecryptUpdate(
ctx: *mut EVP_CIPHER_CTX,
out: *mut c_uchar,
outl: *mut c_int,
in_: *const u8,
inl: c_int,
) -> c_int;
pub fn EVP_DecryptFinal_ex(
ctx: *mut EVP_CIPHER_CTX,
outm: *mut c_uchar,
outl: *mut c_int,
) -> c_int;
}
cfg_if! {
if #[cfg(ossl300)] {
extern "C" {
pub fn EVP_PKEY_get_size(pkey: *const EVP_PKEY) -> c_int;
}
} else {
const_ptr_api! {
extern "C" {
pub fn EVP_PKEY_size(pkey: #[const_ptr_if(any(ossl111b, libressl))] EVP_PKEY) -> c_int;
}
}
}
}
cfg_if! {
if #[cfg(any(ossl111, libressl370))] {
extern "C" {
pub fn EVP_DigestSign(
ctx: *mut EVP_MD_CTX,
sigret: *mut c_uchar,
siglen: *mut size_t,
tbs: *const c_uchar,
tbslen: size_t
) -> c_int;
pub fn EVP_DigestVerify(
ctx: *mut EVP_MD_CTX,
sigret: *const c_uchar,
siglen: size_t,
tbs: *const c_uchar,
tbslen: size_t
) -> c_int;
}
}
}
extern "C" {
pub fn EVP_CIPHER_CTX_new() -> *mut EVP_CIPHER_CTX;
pub fn EVP_CIPHER_CTX_free(ctx: *mut EVP_CIPHER_CTX);
pub fn EVP_CIPHER_CTX_copy(dst: *mut EVP_CIPHER_CTX, src: *const EVP_CIPHER_CTX) -> c_int;
pub fn EVP_MD_CTX_copy_ex(dst: *mut EVP_MD_CTX, src: *const EVP_MD_CTX) -> c_int;
#[cfg(ossl111)]
pub fn EVP_MD_CTX_reset(ctx: *mut EVP_MD_CTX) -> c_int;
pub fn EVP_CIPHER_CTX_set_key_length(ctx: *mut EVP_CIPHER_CTX, keylen: c_int) -> c_int;
pub fn EVP_CIPHER_CTX_set_padding(ctx: *mut EVP_CIPHER_CTX, padding: c_int) -> c_int;
pub fn EVP_CIPHER_CTX_ctrl(
ctx: *mut EVP_CIPHER_CTX,
type_: c_int,
arg: c_int,
ptr: *mut c_void,
) -> c_int;
pub fn EVP_CIPHER_CTX_rand_key(ctx: *mut EVP_CIPHER_CTX, key: *mut c_uchar) -> c_int;
pub fn EVP_CIPHER_CTX_set_flags(ctx: *mut EVP_CIPHER_CTX, flags: c_int);
pub fn EVP_md_null() -> *const EVP_MD;
pub fn EVP_md5() -> *const EVP_MD;
pub fn EVP_sha1() -> *const EVP_MD;
pub fn EVP_sha224() -> *const EVP_MD;
pub fn EVP_sha256() -> *const EVP_MD;
pub fn EVP_sha384() -> *const EVP_MD;
pub fn EVP_sha512() -> *const EVP_MD;
#[cfg(any(ossl111, libressl380))]
pub fn EVP_sha3_224() -> *const EVP_MD;
#[cfg(any(ossl111, libressl380))]
pub fn EVP_sha3_256() -> *const EVP_MD;
#[cfg(any(ossl111, libressl380))]
pub fn EVP_sha3_384() -> *const EVP_MD;
#[cfg(any(ossl111, libressl380))]
pub fn EVP_sha3_512() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_shake128() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_shake256() -> *const EVP_MD;
pub fn EVP_ripemd160() -> *const EVP_MD;
#[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM3")))]
pub fn EVP_sm3() -> *const EVP_MD;
pub fn EVP_des_ecb() -> *const EVP_CIPHER;
pub fn EVP_des_ede3() -> *const EVP_CIPHER;
pub fn EVP_des_ede3_cbc() -> *const EVP_CIPHER;
pub fn EVP_des_ede3_ecb() -> *const EVP_CIPHER;
pub fn EVP_des_ede3_cfb64() -> *const EVP_CIPHER;
pub fn EVP_des_ede3_cfb8() -> *const EVP_CIPHER;
pub fn EVP_des_ede3_ofb() -> *const EVP_CIPHER;
pub fn EVP_des_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
pub fn EVP_rc4() -> *const EVP_CIPHER;
pub fn EVP_bf_ecb() -> *const EVP_CIPHER;
pub fn EVP_bf_cbc() -> *const EVP_CIPHER;
pub fn EVP_bf_cfb64() -> *const EVP_CIPHER;
pub fn EVP_bf_ofb() -> *const EVP_CIPHER;
pub fn EVP_aes_128_ecb() -> *const EVP_CIPHER;
pub fn EVP_aes_128_cbc() -> *const EVP_CIPHER;
pub fn EVP_aes_128_cfb1() -> *const EVP_CIPHER;
pub fn EVP_aes_128_cfb8() -> *const EVP_CIPHER;
pub fn EVP_aes_128_cfb128() -> *const EVP_CIPHER;
pub fn EVP_aes_128_ctr() -> *const EVP_CIPHER;
pub fn EVP_aes_128_ccm() -> *const EVP_CIPHER;
pub fn EVP_aes_128_gcm() -> *const EVP_CIPHER;
pub fn EVP_aes_128_xts() -> *const EVP_CIPHER;
pub fn EVP_aes_128_ofb() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_aes_128_ocb() -> *const EVP_CIPHER;
#[cfg(ossl102)]
pub fn EVP_aes_128_wrap() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_aes_128_wrap_pad() -> *const EVP_CIPHER;
pub fn EVP_aes_192_ecb() -> *const EVP_CIPHER;
pub fn EVP_aes_192_cbc() -> *const EVP_CIPHER;
pub fn EVP_aes_192_cfb1() -> *const EVP_CIPHER;
pub fn EVP_aes_192_cfb8() -> *const EVP_CIPHER;
pub fn EVP_aes_192_cfb128() -> *const EVP_CIPHER;
pub fn EVP_aes_192_ctr() -> *const EVP_CIPHER;
pub fn EVP_aes_192_ccm() -> *const EVP_CIPHER;
pub fn EVP_aes_192_gcm() -> *const EVP_CIPHER;
pub fn EVP_aes_192_ofb() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_aes_192_ocb() -> *const EVP_CIPHER;
#[cfg(ossl102)]
pub fn EVP_aes_192_wrap() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_aes_192_wrap_pad() -> *const EVP_CIPHER;
pub fn EVP_aes_256_ecb() -> *const EVP_CIPHER;
pub fn EVP_aes_256_cbc() -> *const EVP_CIPHER;
pub fn EVP_aes_256_cfb1() -> *const EVP_CIPHER;
pub fn EVP_aes_256_cfb8() -> *const EVP_CIPHER;
pub fn EVP_aes_256_cfb128() -> *const EVP_CIPHER;
pub fn EVP_aes_256_ctr() -> *const EVP_CIPHER;
pub fn EVP_aes_256_ccm() -> *const EVP_CIPHER;
pub fn EVP_aes_256_gcm() -> *const EVP_CIPHER;
pub fn EVP_aes_256_xts() -> *const EVP_CIPHER;
pub fn EVP_aes_256_ofb() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_aes_256_ocb() -> *const EVP_CIPHER;
#[cfg(ossl102)]
pub fn EVP_aes_256_wrap() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_aes_256_wrap_pad() -> *const EVP_CIPHER;
#[cfg(all(any(ossl110, libressl), not(osslconf = "OPENSSL_NO_CHACHA")))]
pub fn EVP_chacha20() -> *const EVP_CIPHER;
#[cfg(all(any(ossl110, libressl360), not(osslconf = "OPENSSL_NO_CHACHA")))]
pub fn EVP_chacha20_poly1305() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
pub fn EVP_seed_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
pub fn EVP_seed_cfb128() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
pub fn EVP_seed_ecb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
pub fn EVP_seed_ofb() -> *const EVP_CIPHER;
#[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
pub fn EVP_sm4_ecb() -> *const EVP_CIPHER;
#[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
pub fn EVP_sm4_cbc() -> *const EVP_CIPHER;
#[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
pub fn EVP_sm4_cfb128() -> *const EVP_CIPHER;
#[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
pub fn EVP_sm4_ofb() -> *const EVP_CIPHER;
#[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
pub fn EVP_sm4_ctr() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_128_cfb128() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_128_ecb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_128_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_128_ofb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_192_cfb128() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_192_ecb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_192_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_192_ofb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_256_cfb128() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_256_ecb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_256_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_256_ofb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn EVP_cast5_cfb64() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn EVP_cast5_ecb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn EVP_cast5_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn EVP_cast5_ofb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn EVP_idea_cfb64() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn EVP_idea_ecb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn EVP_idea_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn EVP_idea_ofb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_RC2"))]
pub fn EVP_rc2_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_RC2"))]
pub fn EVP_rc2_40_cbc() -> *const EVP_CIPHER;
#[cfg(not(ossl110))]
pub fn OPENSSL_add_all_algorithms_noconf();
pub fn EVP_get_digestbyname(name: *const c_char) -> *const EVP_MD;
pub fn EVP_get_cipherbyname(name: *const c_char) -> *const EVP_CIPHER;
}
cfg_if! {
if #[cfg(ossl300)] {
extern "C" {
pub fn EVP_PKEY_get_id(pkey: *const EVP_PKEY) -> c_int;
pub fn EVP_PKEY_get_bits(key: *const EVP_PKEY) -> c_int;
pub fn EVP_PKEY_get_security_bits(key: *const EVP_PKEY) -> c_int;
}
} else {
extern "C" {
pub fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> c_int;
}
const_ptr_api! {
extern "C" {
pub fn EVP_PKEY_bits(key: #[const_ptr_if(any(ossl110, libressl))] EVP_PKEY) -> c_int;
#[cfg(any(ossl110, libressl360))]
pub fn EVP_PKEY_security_bits(pkey: #[const_ptr_if(any(ossl110, libressl))] EVP_PKEY) -> c_int;
}
}
}
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
const_ptr_api! {
extern "C" {
pub fn EVP_PKEY_get1_RSA(k: #[const_ptr_if(libressl420)] EVP_PKEY) -> *mut RSA;
pub fn EVP_PKEY_get1_DSA(k: #[const_ptr_if(libressl420)] EVP_PKEY) -> *mut DSA;
pub fn EVP_PKEY_get1_DH(k: #[const_ptr_if(libressl420)] EVP_PKEY) -> *mut DH;
pub fn EVP_PKEY_get1_EC_KEY(k: #[const_ptr_if(libressl420)] EVP_PKEY) -> *mut EC_KEY;
}
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
extern "C" {
pub fn EVP_PKEY_assign(pkey: *mut EVP_PKEY, typ: c_int, key: *mut c_void) -> c_int;
pub fn EVP_PKEY_set1_RSA(k: *mut EVP_PKEY, r: *mut RSA) -> c_int;
pub fn EVP_PKEY_set1_DSA(k: *mut EVP_PKEY, k: *mut DSA) -> c_int;
pub fn EVP_PKEY_set1_DH(k: *mut EVP_PKEY, k: *mut DH) -> c_int;
pub fn EVP_PKEY_set1_EC_KEY(k: *mut EVP_PKEY, k: *mut EC_KEY) -> c_int;
pub fn EVP_PKEY_cmp(a: *const EVP_PKEY, b: *const EVP_PKEY) -> c_int;
}
extern "C" {
pub fn EVP_PKEY_new() -> *mut EVP_PKEY;
pub fn EVP_PKEY_free(k: *mut EVP_PKEY);
#[cfg(any(ossl110, libressl))]
pub fn EVP_PKEY_up_ref(pkey: *mut EVP_PKEY) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_fromdata_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_fromdata(
ctx: *mut EVP_PKEY_CTX,
ppkey: *mut *mut EVP_PKEY,
selection: c_int,
param: *mut OSSL_PARAM,
) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_todata(
ppkey: *const EVP_PKEY,
selection: c_int,
param: *mut *mut OSSL_PARAM,
) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_generate(ctx: *mut EVP_PKEY_CTX, k: *mut *mut EVP_PKEY) -> c_int;
pub fn d2i_AutoPrivateKey(
a: *mut *mut EVP_PKEY,
pp: *mut *const c_uchar,
length: c_long,
) -> *mut EVP_PKEY;
#[cfg(ossl300)]
pub fn EVP_PKEY_eq(a: *const EVP_PKEY, b: *const EVP_PKEY) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_parameters_eq(a: *const EVP_PKEY, b: *const EVP_PKEY) -> c_int;
pub fn EVP_PKEY_copy_parameters(to: *mut EVP_PKEY, from: *const EVP_PKEY) -> c_int;
pub fn PKCS5_PBKDF2_HMAC_SHA1(
pass: *const c_char,
passlen: c_int,
salt: *const u8,
saltlen: c_int,
iter: c_int,
keylen: c_int,
out: *mut u8,
) -> c_int;
pub fn PKCS5_PBKDF2_HMAC(
pass: *const c_char,
passlen: c_int,
salt: *const c_uchar,
saltlen: c_int,
iter: c_int,
digest: *const EVP_MD,
keylen: c_int,
out: *mut u8,
) -> c_int;
#[cfg(ossl110)]
pub fn EVP_PBE_scrypt(
pass: *const c_char,
passlen: size_t,
salt: *const c_uchar,
saltlen: size_t,
N: u64,
r: u64,
p: u64,
maxmem: u64,
key: *mut c_uchar,
keylen: size_t,
) -> c_int;
pub fn EVP_PKEY_CTX_new(k: *mut EVP_PKEY, e: *mut ENGINE) -> *mut EVP_PKEY_CTX;
pub fn EVP_PKEY_CTX_new_id(id: c_int, e: *mut ENGINE) -> *mut EVP_PKEY_CTX;
#[cfg(ossl300)]
pub fn EVP_PKEY_CTX_new_from_name(
libctx: *mut OSSL_LIB_CTX,
name: *const c_char,
propquery: *const c_char,
) -> *mut EVP_PKEY_CTX;
pub fn EVP_PKEY_CTX_free(ctx: *mut EVP_PKEY_CTX);
pub fn EVP_PKEY_CTX_ctrl(
ctx: *mut EVP_PKEY_CTX,
keytype: c_int,
optype: c_int,
cmd: c_int,
p1: c_int,
p2: *mut c_void,
) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_CTX_set_signature_md(ctx: *mut EVP_PKEY_CTX, md: *const EVP_MD) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_CTX_set_params(ctx: *mut EVP_PKEY_CTX, params: *const OSSL_PARAM) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_CTX_get_params(ctx: *mut EVP_PKEY_CTX, params: *mut OSSL_PARAM) -> c_int;
pub fn EVP_PKEY_new_mac_key(
type_: c_int,
e: *mut ENGINE,
key: *const c_uchar,
keylen: c_int,
) -> *mut EVP_PKEY;
pub fn EVP_PKEY_derive_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
pub fn EVP_PKEY_derive_set_peer(ctx: *mut EVP_PKEY_CTX, peer: *mut EVP_PKEY) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_derive_set_peer_ex(
ctx: *mut EVP_PKEY_CTX,
peer: *mut EVP_PKEY,
validate_peer: c_int,
) -> c_int;
pub fn EVP_PKEY_derive(ctx: *mut EVP_PKEY_CTX, key: *mut c_uchar, size: *mut size_t) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_Q_keygen(
libctx: *mut OSSL_LIB_CTX,
propq: *const c_char,
type_: *const c_char,
...
) -> *mut EVP_PKEY;
pub fn EVP_PKEY_keygen_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
pub fn EVP_PKEY_paramgen_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
pub fn EVP_PKEY_keygen(ctx: *mut EVP_PKEY_CTX, key: *mut *mut EVP_PKEY) -> c_int;
pub fn EVP_PKEY_paramgen(ctx: *mut EVP_PKEY_CTX, key: *mut *mut EVP_PKEY) -> c_int;
#[cfg(ossl111)]
pub fn EVP_PKEY_param_check(ctx: *mut EVP_PKEY_CTX) -> c_int;
#[cfg(ossl111)]
pub fn EVP_PKEY_public_check(ctx: *mut EVP_PKEY_CTX) -> c_int;
#[cfg(ossl111)]
pub fn EVP_PKEY_check(ctx: *mut EVP_PKEY_CTX) -> c_int;
pub fn EVP_PKEY_sign_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
#[cfg(ossl340)]
pub fn EVP_PKEY_sign_message_init(
ctx: *mut EVP_PKEY_CTX,
algo: *mut EVP_SIGNATURE,
params: *const OSSL_PARAM,
) -> c_int;
pub fn EVP_PKEY_sign(
ctx: *mut EVP_PKEY_CTX,
sig: *mut c_uchar,
siglen: *mut size_t,
tbs: *const c_uchar,
tbslen: size_t,
) -> c_int;
pub fn EVP_PKEY_verify_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
#[cfg(ossl340)]
pub fn EVP_PKEY_verify_message_init(
ctx: *mut EVP_PKEY_CTX,
algo: *mut EVP_SIGNATURE,
params: *const OSSL_PARAM,
) -> c_int;
pub fn EVP_PKEY_verify(
ctx: *mut EVP_PKEY_CTX,
sig: *const c_uchar,
siglen: size_t,
tbs: *const c_uchar,
tbslen: size_t,
) -> c_int;
pub fn EVP_PKEY_encrypt_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
pub fn EVP_PKEY_encrypt(
ctx: *mut EVP_PKEY_CTX,
pout: *mut c_uchar,
poutlen: *mut size_t,
pin: *const c_uchar,
pinlen: size_t,
) -> c_int;
pub fn EVP_PKEY_decrypt_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
pub fn EVP_PKEY_decrypt(
ctx: *mut EVP_PKEY_CTX,
pout: *mut c_uchar,
poutlen: *mut size_t,
pin: *const c_uchar,
pinlen: size_t,
) -> c_int;
pub fn EVP_PKEY_verify_recover_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
pub fn EVP_PKEY_verify_recover(
ctx: *mut EVP_PKEY_CTX,
rout: *mut c_uchar,
routlen: *mut size_t,
sig: *const c_uchar,
siglen: size_t,
) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_encapsulate_init(ctx: *mut EVP_PKEY_CTX, params: *const OSSL_PARAM) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_encapsulate(
ctx: *mut EVP_PKEY_CTX,
wrappedkey: *mut c_uchar,
wrappedkeylen: *mut size_t,
genkey: *mut c_uchar,
genkeylen: *mut size_t,
) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_decapsulate_init(ctx: *mut EVP_PKEY_CTX, params: *const OSSL_PARAM) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_decapsulate(
ctx: *mut EVP_PKEY_CTX,
genkey: *mut c_uchar,
genkeylen: *mut size_t,
wrappedkey: *const c_uchar,
wrappedkeylen: size_t,
) -> c_int;
}
const_ptr_api! {
extern "C" {
pub fn EVP_PKCS82PKEY(p8: #[const_ptr_if(any(ossl110, libressl))] PKCS8_PRIV_KEY_INFO) -> *mut EVP_PKEY;
pub fn EVP_PKEY2PKCS8(pkey: #[const_ptr_if(any(ossl300))] EVP_PKEY) -> *mut PKCS8_PRIV_KEY_INFO;
}
}
cfg_if! {
if #[cfg(any(ossl111, libressl370))] {
extern "C" {
pub fn EVP_PKEY_get_raw_public_key(
pkey: *const EVP_PKEY,
ppub: *mut c_uchar,
len: *mut size_t,
) -> c_int;
pub fn EVP_PKEY_new_raw_public_key(
ttype: c_int,
e: *mut ENGINE,
key: *const c_uchar,
keylen: size_t,
) -> *mut EVP_PKEY;
pub fn EVP_PKEY_get_raw_private_key(
pkey: *const EVP_PKEY,
ppriv: *mut c_uchar,
len: *mut size_t,
) -> c_int;
pub fn EVP_PKEY_new_raw_private_key(
ttype: c_int,
e: *mut ENGINE,
key: *const c_uchar,
keylen: size_t,
) -> *mut EVP_PKEY;
}
}
}
extern "C" {
pub fn EVP_EncodeBlock(dst: *mut c_uchar, src: *const c_uchar, src_len: c_int) -> c_int;
pub fn EVP_DecodeBlock(dst: *mut c_uchar, src: *const c_uchar, src_len: c_int) -> c_int;
}
cfg_if! {
if #[cfg(ossl300)] {
extern "C" {
pub fn EVP_PKEY_gettable_params(pkey: *const EVP_PKEY) -> *const OSSL_PARAM;
pub fn EVP_PKEY_get_params(pkey: *const EVP_PKEY, params: *mut OSSL_PARAM) -> c_int;
pub fn EVP_PKEY_get_int_param(
pkey: *const EVP_PKEY,
key_name: *const c_char,
out: *mut c_int,
) -> c_int;
pub fn EVP_PKEY_get_size_t_param(
pkey: *const EVP_PKEY,
key_name: *const c_char,
out: *mut size_t,
) -> c_int;
pub fn EVP_PKEY_get_bn_param(
pkey: *const EVP_PKEY,
key_name: *const c_char,
out: *mut *mut BIGNUM,
) -> c_int;
pub fn EVP_PKEY_get_utf8_string_param(
pkey: *const EVP_PKEY,
key_name: *const c_char,
str: *mut c_char,
max_buf_sz: size_t,
out_len: *mut size_t,
) -> c_int;
pub fn EVP_PKEY_get_octet_string_param(
pkey: *const EVP_PKEY,
key_name: *const c_char,
buf: *mut c_uchar,
max_buf_sz: size_t,
out_len: *mut size_t,
) -> c_int;
pub fn EVP_PKEY_settable_params(pkey: *const EVP_PKEY) -> *const OSSL_PARAM;
pub fn EVP_PKEY_set_params(pkey: *mut EVP_PKEY, params: *mut OSSL_PARAM) -> c_int;
pub fn EVP_PKEY_set_int_param(
pkey: *mut EVP_PKEY,
key_name: *const c_char,
in_val: c_int,
) -> c_int;
pub fn EVP_PKEY_set_size_t_param(
pkey: *mut EVP_PKEY,
key_name: *const c_char,
in_val: size_t,
) -> c_int;
pub fn EVP_PKEY_set_bn_param(
pkey: *mut EVP_PKEY,
key_name: *const c_char,
bn: *const BIGNUM,
) -> c_int;
pub fn EVP_PKEY_set_utf8_string_param(
pkey: *mut EVP_PKEY,
key_name: *const c_char,
str: *const c_char,
) -> c_int;
pub fn EVP_PKEY_set_octet_string_param(
pkey: *mut EVP_PKEY,
key_name: *const c_char,
buf: *const c_uchar,
bsize: size_t,
) -> c_int;
pub fn EVP_SIGNATURE_free(s: *mut EVP_SIGNATURE);
pub fn EVP_SIGNATURE_up_ref(s: *mut EVP_SIGNATURE) -> c_int;
pub fn EVP_SIGNATURE_fetch(ctx: *mut OSSL_LIB_CTX,
algorithm: *const c_char,
properties: *const c_char)
-> *mut EVP_SIGNATURE;
pub fn EVP_SIGNATURE_get0_name(s: *const EVP_SIGNATURE) -> *const c_char;
pub fn EVP_SIGNATURE_get0_description(s: *const EVP_SIGNATURE) -> *const c_char;
}
}
}
cfg_if! {
if #[cfg(ossl300)] {
extern "C" {
pub fn EVP_MAC_fetch(libctx: *mut OSSL_LIB_CTX, algorithm: *const c_char, properties: *const c_char) -> *mut EVP_MAC;
pub fn EVP_MAC_up_ref(mac: *mut EVP_MAC) -> c_int;
pub fn EVP_MAC_free(mac: *mut EVP_MAC);
pub fn EVP_MAC_is_a(mac: *const EVP_MAC, name: *const c_char) -> c_int;
pub fn EVP_MAC_get0_name(mac: *const EVP_MAC) -> *const c_char;
pub fn EVP_MAC_get0_description(mac: *const EVP_MAC) -> *const c_char;
pub fn EVP_MAC_get0_provider(mac: *const EVP_MAC) -> *const OSSL_PROVIDER;
pub fn EVP_MAC_get_params(mac: *mut EVP_MAC, params: *mut OSSL_PARAM) -> c_int;
pub fn EVP_MAC_CTX_new(mac: *mut EVP_MAC) -> *mut EVP_MAC_CTX;
pub fn EVP_MAC_CTX_free(ctx: *mut EVP_MAC_CTX);
pub fn EVP_MAC_CTX_dup(src: *const EVP_MAC_CTX) -> *mut EVP_MAC_CTX;
pub fn EVP_MAC_CTX_get0_mac(ctx: *mut EVP_MAC_CTX) -> *mut EVP_MAC;
pub fn EVP_MAC_CTX_get_params(ctx: *mut EVP_MAC_CTX, params: *mut OSSL_PARAM) -> c_int;
pub fn EVP_MAC_CTX_set_params(ctx: *mut EVP_MAC_CTX, params: *const OSSL_PARAM) -> c_int;
pub fn EVP_MAC_CTX_get_mac_size(ctx: *mut EVP_MAC_CTX) -> size_t;
pub fn EVP_MAC_CTX_get_block_size(ctx: *mut EVP_MAC_CTX) -> size_t;
pub fn EVP_MAC_init(ctx: *mut EVP_MAC_CTX, key: *const c_uchar, keylen: size_t, params: *const OSSL_PARAM) -> c_int;
pub fn EVP_MAC_update(ctx: *mut EVP_MAC_CTX, data: *const c_uchar, datalen: size_t) -> c_int;
pub fn EVP_MAC_final(ctx: *mut EVP_MAC_CTX, out: *mut c_uchar, outl: *mut size_t, outsize: size_t) -> c_int;
pub fn EVP_MAC_finalXOF(ctx: *mut EVP_MAC_CTX, out: *mut c_uchar, outsize: size_t) -> c_int;
pub fn EVP_MAC_gettable_params(mac: *const EVP_MAC) -> *const OSSL_PARAM;
pub fn EVP_MAC_gettable_ctx_params(mac: *const EVP_MAC) -> *const OSSL_PARAM;
pub fn EVP_MAC_settable_ctx_params(mac: *const EVP_MAC) -> *const OSSL_PARAM;
pub fn EVP_MAC_CTX_gettable_params(ctx: *mut EVP_MAC_CTX) -> *const OSSL_PARAM;
pub fn EVP_MAC_CTX_settable_params(ctx: *mut EVP_MAC_CTX) -> *const OSSL_PARAM;
}
}
}

View File

@@ -0,0 +1,32 @@
use cratecrate::cratecrate::crate::libc::*;
use super::super::*;
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
cfg_if! {
if #[cfg(any(ossl110, libressl))] {
extern "C" {
pub fn HMAC_CTX_new() -> *mut HMAC_CTX;
pub fn HMAC_CTX_free(ctx: *mut HMAC_CTX);
}
} else {
extern "C" {
pub fn HMAC_CTX_init(ctx: *mut HMAC_CTX);
pub fn HMAC_CTX_cleanup(ctx: *mut HMAC_CTX);
}
}
}
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
extern "C" {
pub fn HMAC_Init_ex(
ctx: *mut HMAC_CTX,
key: *const c_void,
len: c_int,
md: *const EVP_MD,
impl_: *mut ENGINE,
) -> c_int;
pub fn HMAC_Update(ctx: *mut HMAC_CTX, data: *const c_uchar, len: size_t) -> c_int;
pub fn HMAC_Final(ctx: *mut HMAC_CTX, md: *mut c_uchar, len: *mut c_uint) -> c_int;
pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *mut HMAC_CTX) -> c_int;
}

Some files were not shown because too many files have changed in this diff Show More