Installation Add the package via Composer:
composer require vakata/asn1
No additional configuration is required for basic usage.
First Use Case: Parsing ASN.1 Data
Import the Vakata\ASN1 namespace and parse a DER-encoded string:
use Vakata\ASN1\ASN1;
$derData = file_get_contents('path/to/der.der');
$asn1 = ASN1::decode($derData);
print_r($asn1);
Output will be a structured array representing the ASN.1 data.
First Use Case: Building ASN.1 Data Construct a simple ASN.1 structure and encode it:
use Vakata\ASN1\ASN1;
$data = [
'integer' => 123,
'string' => 'Hello, ASN1!',
'sequence' => [
'octet-string' => hex2bin('12345678'),
],
];
$encoded = ASN1::encode($data);
file_put_contents('output.der', $encoded);
Key Classes to Know
ASN1: Main class for encoding/decoding.ASN1Element: Represents individual ASN.1 elements (e.g., integers, sequences).ASN1Exception: Handle parsing/encoding errors.ASN.1 is widely used in X.509 certificates and CSRs. Parse a certificate:
$certData = file_get_contents('cert.der');
$cert = ASN1::decode($certData);
// Extract subject (assuming it's a sequence)
$subject = $cert['tbsCertificate']['subject'];
Construct a PKCS#12 AuthSafe structure:
$p12Data = [
'authSafe' => [
'version' => 0,
'friendlyName' => 'My Certificate',
'localKeyId' => hex2bin('1234567890abcdef'),
'data' => [
'certificate' => $certificateData,
'privateKey' => $privateKeyData,
],
],
];
$encodedP12 = ASN1::encode($p12Data);
Use OIDs to tag structures (e.g., for extensions):
$extension = [
'id' => '1.2.3.4.5', // Example OID
'critical' => false,
'value' => $criticalExtensionData,
];
ASN.1 often nests structures. Traverse recursively:
function traverseASN1($data, $path = '') {
foreach ($data as $key => $value) {
$currentPath = $path ? "$path.$key" : $key;
if (is_array($value)) {
traverseASN1($value, $currentPath);
} else {
echo "Path: $currentPath, Value: " . print_r($value, true);
}
}
}
traverseASN1($asn1Data);
Register the package as a singleton for global access:
// app/Providers/AppServiceProvider.php
public function register() {
$this->app->singleton('asn1', function () {
return new \Vakata\ASN1\ASN1();
});
}
Use it in controllers:
$asn1 = app('asn1');
$data = $asn1->decode($request->file('cert')->getContent());
Create a command to validate ASN.1 files:
// app/Console/Commands/ValidateAsn1.php
public function handle() {
$file = $this->argument('file');
$asn1 = ASN1::decode(file_get_contents($file));
$this->info('ASN.1 file is valid!');
}
Register it in app/Console/Kernel.php:
protected $commands = [
\App\Console\Commands\ValidateAsn1::class,
];
Validate ASN.1 data in Laravel requests:
public function rules() {
return [
'certificate' => 'required|file|mimes:der',
];
}
public function withValidator($validator) {
$validator->after(function ($validator) {
if ($validator->errors()->any()) return;
$certData = file_get_contents($this->certificate->getRealPath());
try {
ASN1::decode($certData);
} catch (ASN1Exception $e) {
$validator->errors()->add('certificate', 'Invalid ASN.1 format.');
}
});
}
Return ASN.1-encoded data in API responses:
return response()->json([
'asn1_data' => base64_encode(ASN1::encode($data)),
]);
openssl asn1parse to verify encoding rules.$data = [
'tag:0' => [ // Explicit tag 0
'value' => 'data',
],
];
hex2bin for manual hex strings to avoid encoding issues.$asn1 = ASN1::decode($data, ASN1::STRICT);
Use print_r with ASN1Element objects:
function prettyPrintASN1($data, $indent = 0) {
foreach ($data as $key => $value) {
echo str_repeat(' ', $indent) . "$key: ";
if (is_array($value)) {
echo "\n";
prettyPrintASN1($value, $indent + 1);
} else {
echo print_r($value, true) . "\n";
}
}
}
prettyPrintASN1($asn1Data);
Cross-validate parsed data using OpenSSL CLI:
openssl asn1parse -in input.der -inform DER
Wrap decoding in a try-catch:
try {
$data = ASN1::decode($derData);
} catch (ASN1Exception $e) {
Log::error('ASN.1 decode error: ' . $e->getMessage());
throw new \Exception('Invalid ASN.1 data');
}
Extend the parser to handle proprietary tags:
ASN1::setTagHandler(1234, function ($value) {
return ['custom' => $value];
});
Override default behavior:
ASN1::setEncoderHook('integer', function ($value) {
return hex2bin(dechex($value)); // Custom encoding
});
Store ASN.1 files in Laravel storage:
use Illuminate\Support\Facades\Storage;
$path = Storage::disk('s3')->put('certs/cert.der', $encodedData);
How can I help you explore Laravel packages today?