diff --git a/app/Classes/LDAP/Attribute.php b/app/Classes/LDAP/Attribute.php
index 82c22ef9..0e2c9380 100644
--- a/app/Classes/LDAP/Attribute.php
+++ b/app/Classes/LDAP/Attribute.php
@@ -16,7 +16,6 @@ class Attribute implements \Countable, \ArrayAccess
 {
 	// Attribute Name
 	protected string $name;
-	private int $counter = 0;
 
 	// Is this attribute an internal attribute
 	protected(set) bool $is_internal = FALSE;
diff --git a/app/Classes/LDAP/Attribute/Factory.php b/app/Classes/LDAP/Attribute/Factory.php
index 3d23fc9e..457f633b 100644
--- a/app/Classes/LDAP/Attribute/Factory.php
+++ b/app/Classes/LDAP/Attribute/Factory.php
@@ -52,6 +52,7 @@ class Factory
 		'supportedfeatures' => Schema\OID::class,
 		'supportedldapversion' => Schema\Generic::class,
 		'supportedsaslmechanisms' => Schema\Mechanisms::class,
+		'usercertificate' => UserCertificate::class,
 		'userpassword' => Password::class,
 	];
 
diff --git a/app/Classes/LDAP/Attribute/UserCertificate.php b/app/Classes/LDAP/Attribute/UserCertificate.php
new file mode 100644
index 00000000..eba299bb
--- /dev/null
+++ b/app/Classes/LDAP/Attribute/UserCertificate.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace App\Classes\LDAP\Attribute;
+
+use Carbon\Carbon;
+use Illuminate\Support\Arr;
+
+use App\Classes\LDAP\Attribute;
+use App\Traits\MD5Updates;
+
+/**
+ * Represents an attribute whose values is a binary user certificate
+ */
+final class UserCertificate extends Attribute
+{
+	use MD5Updates;
+
+	private array $_object = [];
+
+	public function certificate(int $key=0): string
+	{
+		return sprintf("-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----",
+			join("\n",str_split(base64_encode(Arr::get($this->values_old,'binary.'.$key)),80))
+		);
+	}
+
+	public function cert_info(string $index,int $key=0): mixed
+	{
+		if (! array_key_exists($key,$this->_object))
+			$this->_object[$key] = openssl_x509_parse(openssl_x509_read($this->certificate($key)));
+
+
+		return Arr::get($this->_object[$key],$index);
+	}
+
+	public function expires($key=0): Carbon
+	{
+		return Carbon::createFromTimestampUTC($this->cert_info('validTo_time_t',$key));
+	}
+
+	public function render_item_old(string $dotkey): ?string
+	{
+		return join("\n",str_split(base64_encode(parent::render_item_old($dotkey)),80));
+	}
+
+	public function subject($key=0): string
+	{
+		$subject = collect($this->cert_info('subject',$key))->reverse();
+
+		return $subject->map(fn($item,$key)=>sprintf("%s=%s",$key,$item))->join(',');
+	}
+}
\ No newline at end of file
diff --git a/app/Ldap/Entry.php b/app/Ldap/Entry.php
index 741ee998..5eddd64f 100644
--- a/app/Ldap/Entry.php
+++ b/app/Ldap/Entry.php
@@ -389,7 +389,6 @@ class Entry extends Model
 						fn($item)=>
 							(! preg_match(sprintf('/^%s$/',self::TAG_NOTAG),$item))
 							&& (! preg_match(sprintf('/^%s+$/',self::TAG_CHARS_LANG),$item))
-							&& (! preg_match('/^binary$/',$item))
 						)
 						->count())
 			)
@@ -428,9 +427,17 @@ class Entry extends Model
 	 */
 	public function getVisibleAttributes(?string $tag=NULL): Collection
 	{
-		return $this->objects
-			->filter(fn($item)=>! $item->is_internal)
-			->filter(fn($item)=>is_null($tag) || count($item->tagValues($tag)) > 0);
+		static $cache = NULL;
+
+		if (is_null($cache)) {
+			$ot = $this->getOtherTags();
+
+			$cache = $this->objects
+				->filter(fn($item)=>! $item->is_internal)
+				->filter(fn($item)=>is_null($tag) || $ot->has($item->name_lc) || count($item->tagValues($tag)) > 0);
+		}
+
+		return $cache;
 	}
 
 	public function hasAttribute(int|string $key): bool
diff --git a/composer.json b/composer.json
index ff2cc10d..eeb735db 100644
--- a/composer.json
+++ b/composer.json
@@ -7,6 +7,7 @@
     "require": {
         "ext-fileinfo": "*",
         "ext-ldap": "*",
+        "ext-openssl": "*",
         "php": "^8.4",
         "directorytree/ldaprecord-laravel": "^3.0",
         "laravel/framework": "^11.9",
diff --git a/resources/views/components/attribute/usercertificate.blade.php b/resources/views/components/attribute/usercertificate.blade.php
new file mode 100644
index 00000000..41e37457
--- /dev/null
+++ b/resources/views/components/attribute/usercertificate.blade.php
@@ -0,0 +1,25 @@
+<!-- $o=UserCertificate::class -->
+<x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o" langtag="binary">
+	@foreach($o->tagValuesOld('binary') as $key => $value)
+		@if($edit)
+			<input type="hidden" name="name={{ $o->name_lc }}[binary][]" value="{{ md5($value) }}">
+
+			<div class="input-group has-validation mb-3">
+				<textarea class="form-control mb-1 font-monospace" rows="{{ count(explode("\n",$x=$o->certificate())) }}" style="overflow:hidden" disabled>{{ $x }}</textarea>
+
+				<div class="invalid-feedback pb-2">
+					@if($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index))
+						{{ join('|',$e) }}
+					@endif
+				</div>
+			</div>
+			<div class="input-helper">
+				@lang('Certificate Subject'): <strong>{{ $o->subject($loop->index) }}</strong><br/>
+				{{ ($expire=$o->expires($loop->index))->isPast() ? __('Expired') : __('Expires') }}: <strong>{{ $expire->format(config('pla.datetime_format','Y-m-d H:i:s')) }}</strong>
+			</div>
+
+		@else
+			<span class="form-control mb-1"><pre class="m-0">{{ $o->render_item_old('binary.'.$key) }}</pre></span>
+		@endif
+	@endforeach
+</x-attribute.layout>
\ No newline at end of file
diff --git a/resources/views/components/attribute/widget/options.blade.php b/resources/views/components/attribute/widget/options.blade.php
index 75065534..f33b42ba 100644
--- a/resources/views/components/attribute/widget/options.blade.php
+++ b/resources/views/components/attribute/widget/options.blade.php
@@ -1,16 +1,12 @@
 @use(App\Classes\LDAP\Attribute\Binary\JpegPhoto)
 @use(App\Classes\LDAP\Attribute\ObjectClass)
+@use(App\Classes\LDAP\Attribute\UserCertificate)
 @php($clone=FALSE)
 <span class="p-0 m-0">
 	@if($o->is_rdn)
 		<button class="btn btn-sm btn-outline-focus mt-3" disabled><i class="fas fa-fw fa-exchange"></i> @lang('Rename')</button>
 	@elseif($edit && $o->can_addvalues)
 		@switch(get_class($o))
-			@case(JpegPhoto::class)
-				<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name_lc }}" disabled><i class="fas fa-fw fa-plus"></i> @lang('Upload JpegPhoto')</span>
-
-				@break
-
 			@case(ObjectClass::class)
 				<span type="button" @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) data-bs-toggle="modal" data-bs-target="#new_objectclass-modal"><i class="fas fa-fw fa-plus"></i> @lang('Add Objectclass')</span>
 
@@ -216,6 +212,36 @@
 				@append
 				@break
 
+			@case(JpegPhoto::class)
+				<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-upload" disabled><i class="fas fa-fw fa-file-arrow-up"></i> @lang('Upload JpegPhoto')</span>
+				@section('page-scripts')
+					<script type="text/javascript">
+							$(document).ready(function() {
+								$('#{{ $o->name }}-upload.addable').click(function(e) {
+									alert('Sorry, not implemented yet');
+									e.preventDefault();
+									return false;
+								});
+							});
+					</script>
+				@append
+				@break
+
+			@case(UserCertificate::class)
+				<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-replace" disabled><i class="fas fa-fw fa-certificate"></i> @lang('Replace Certificate')</span>
+				@section('page-scripts')
+					<script type="text/javascript">
+							$(document).ready(function() {
+								$('#{{ $o->name }}-replace.addable').click(function(e) {
+									alert('Sorry, not implemented yet');
+									e.preventDefault();
+									return false;
+								});
+							});
+					</script>
+				@append
+				@break
+
 			<!-- All other attributes -->
 			@default
 				@php($clone=TRUE)
diff --git a/resources/views/frames/dn.blade.php b/resources/views/frames/dn.blade.php
index 6cd68ba2..02cd7223 100644
--- a/resources/views/frames/dn.blade.php
+++ b/resources/views/frames/dn.blade.php
@@ -54,7 +54,7 @@
 
 	<div class="row">
 		<div class="col">
-			@if(($x=$o->getOtherTags())->count())
+			@if(($x=$o->getOtherTags()->filter(fn($item)=>$item->diff(['binary'])->count()))->count())
 				<div class="ms-4 mt-4 alert alert-danger p-2" style="max-width: 30em; font-size: 0.80em;">
 					This entry has [<strong>{!! $x->flatten()->join('</strong>, <strong>') !!}</strong>] tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA. You can though manage those tags with an LDIF import.
 				</div>